Commit 1341ddb9 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge branch 'develop' into debug/devnet-ci

parents ab7f5402 9d435aec
---
'@eth-optimism/foundry': minor
---
Initial release, pin to b7b1ec471bdd38221773e1a569dc4f20297bd7db
---
'@eth-optimism/contracts-bedrock': patch
---
Port RLPWriter tests
---
'@eth-optimism/ci-builder': patch
---
Use ethereumoptimism/foundry:latest
......@@ -2,4 +2,4 @@
'@eth-optimism/contracts-bedrock': patch
---
Move encoding and hashing into Encoding and Hashing libraries
Cleans up natspec in MerkleTrie and SecureMerkleTrie contracts
---
'@eth-optimism/contracts-bedrock': patch
---
Fix solc warnings in ProxyAdmin
---
'@eth-optimism/contracts-bedrock': patch
---
Remove unnecessary DefaultValues library
---
'@eth-optimism/contracts-bedrock': patch
---
Fixes a bug that caused L2 timestamps to be computed incorrectly
---
'@eth-optimism/contracts-bedrock': patch
---
Standardizes comments, errors, and events for contracts in the /universal package
---
'@eth-optimism/contracts-bedrock': patch
---
Bump typechain to 8.1.0
---
'@eth-optimism/contracts-bedrock': patch
---
Clean up comments and errors for legacy contracts
---
'@eth-optimism/contracts-bedrock': patch
---
Cleaned up enums, should be CapitalCase enums and UPPER_CASE values
---
'@eth-optimism/contracts-bedrock': patch
---
Update to new L2 tx hash style for deposits
---
'@eth-optimism/contracts-bedrock': patch
---
Standardizes initialization logic for L1 contracts
---
'@eth-optimism/contracts-bedrock': patch
---
Move contracts written by external parties into a vendor folder
......@@ -2,4 +2,4 @@
'@eth-optimism/contracts-bedrock': patch
---
Use external version of ExcessivelySafeCall
Minor cleanups to initialization and semver for L1 contracts
---
'@eth-optimism/contracts-bedrock': patch
---
Reduce the number of compiler warnings
---
'@eth-optimism/contracts-bedrock': patch
---
Remove storage slot buffer in xdomain messengers
---
'@eth-optimism/contracts-bedrock': patch
---
Cleans up initialization logic everywhere
---
'@eth-optimism/contracts-bedrock': patch
---
Rename OptimismMintableTokenFactory to OptimismMintableERC20Factory
---
'@eth-optimism/foundry': patch
---
Use alpine:3.14
---
'@eth-optimism/contracts-bedrock': patch
---
Fix initialization logic
---
'@eth-optimism/contracts-bedrock': patch
---
Clean up the PredeployAddresses library
---
'@eth-optimism/hardhat-deploy-config': patch
---
Use lazyObject
---
'@eth-optimism/contracts-bedrock': patch
---
Tests for RLPReader
---
'@eth-optimism/indexer': patch
---
Fix contract bindings
---
'@eth-optimism/contracts-bedrock': patch
'@eth-optimism/contracts-periphery': patch
---
Bump forge-std to 62caef29b0f87a2c6aaaf634b2ca4c09b6867c92
---
'@eth-optimism/contracts-bedrock': patch
---
Add semver to L2 contracts
---
'@eth-optimism/contracts-bedrock': patch
---
Resolve compiler warnings in Proxy.sol
---
'@eth-optimism/contracts-periphery': minor
---
Fixes a bug in the OptimismMintableERC721. Requires an interface change, so this is a minor and not patch.
---
'@eth-optimism/l2geth': patch
---
fix NPE in debug_standardTraceBlockToFile
---
'@eth-optimism/contracts-bedrock': patch
'@eth-optimism/core-utils': patch
---
Move the `DepositTx` type to `core-utils`. This way it can be more easily used across projects
---
'@eth-optimism/ci-builder': minor
---
Update foundry in ci builder
---
'@eth-optimism/contracts-bedrock': minor
---
Remove Lib* and OVM* prefixes from all contracts
---
'@eth-optimism/contracts-bedrock': patch
---
Remove "not implemented" errors in virtual functions
---
'@eth-optimism/contracts-bedrock': patch
---
Update typechain pipeline
---
'@eth-optimism/contracts-bedrock': patch
'@eth-optimism/contracts-periphery': patch
'@eth-optimism/fault-detector': patch
'@eth-optimism/hardhat-deploy-config': patch
---
Update dev deps
......@@ -127,7 +127,9 @@ jobs:
working_directory: packages/contracts-bedrock
- run:
name: slither
command: yarn slither || exit 0
command: |
slither --version
yarn slither || exit 0
working_directory: packages/contracts-bedrock
- run:
name: test
......@@ -137,12 +139,30 @@ jobs:
name: gas snapshot
command: |
forge --version
forge snapshot --check
forge snapshot --check || exit 0
working_directory: packages/contracts-bedrock
- run:
name: storage snapshot
command: yarn storage-snapshot && git diff --exit-code .storage-layout
working_directory: packages/contracts-bedrock
op-bindings-build:
docker:
- image: ethereumoptimism/ci-builder:latest
resource_class: medium
steps:
- restore_cache:
keys:
- v2-cache-yarn-build-{{ .Revision }}
- checkout
- run:
name: Check if we should run
command: |
shopt -s inherit_errexit
CHANGED=$(check-changed "(contracts-bedrock|op-bindings)")
if [[ "$CHANGED" = "FALSE" ]]; then
circleci step halt
fi
- run:
name: check go bindings
command: make && git diff --exit-code
......@@ -399,6 +419,9 @@ jobs:
environment:
DOCKER_BUILDKIT: 1
steps:
- run:
name: temporary pause
command: circleci step halt
- checkout
- run:
name: Check if we should run
......@@ -545,6 +568,9 @@ workflows:
- contracts-bedrock-tests:
requires:
- yarn-monorepo
- op-bindings-build:
requires:
- yarn-monorepo
- js-lint-test:
name: contracts-governance-tests
package_name: contracts-governance
......
......@@ -232,7 +232,7 @@ jobs:
- name: Publish ci-builder
uses: docker/build-push-action@v2
with:
context: .
context: ./ops/docker/ci-builder
file: ./ops/docker/ci-builder/Dockerfile
push: true
tags: ethereumoptimism/ci-builder:${{ needs.release.outputs.ci-builder }},ethereumoptimism/ci-builder:latest
......
# @eth-optimism/indexer
## 0.1.3
### Patch Changes
- f30a5d39: Fix contract bindings
## 0.1.2
### Patch Changes
......
{
"name": "@eth-optimism/indexer",
"version": "0.1.2",
"version": "0.1.3",
"private": true,
"license": "MIT"
}
......@@ -29,10 +29,10 @@
},
"devDependencies": {
"@babel/eslint-parser": "^7.5.4",
"@eth-optimism/contracts": "^0.5.29",
"@eth-optimism/contracts-periphery": "^0.1.3",
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/sdk": "1.2.0",
"@eth-optimism/contracts": "^0.5.30",
"@eth-optimism/contracts-periphery": "^0.2.0",
"@eth-optimism/core-utils": "0.9.1",
"@eth-optimism/sdk": "1.3.0",
"@ethersproject/abstract-provider": "^5.6.1",
"@ethersproject/providers": "^5.6.8",
"@ethersproject/transactions": "^5.6.2",
......
......@@ -4,8 +4,8 @@ import { ethers } from 'hardhat'
import { getChainId } from '@eth-optimism/core-utils'
import { predeploys } from '@eth-optimism/contracts'
import Artifact__TestERC721 from '@eth-optimism/contracts-periphery/artifacts/contracts/testing/helpers/TestERC721.sol/TestERC721.json'
import Artifact__L1ERC721Bridge from '@eth-optimism/contracts-periphery/artifacts/contracts/L1/messaging/L1ERC721Bridge.sol/L1ERC721Bridge.json'
import Artifact__L2ERC721Bridge from '@eth-optimism/contracts-periphery/artifacts/contracts/L2/messaging/L2ERC721Bridge.sol/L2ERC721Bridge.json'
import Artifact__L1ERC721Bridge from '@eth-optimism/contracts-periphery/artifacts/contracts/L1/L1ERC721Bridge.sol/L1ERC721Bridge.json'
import Artifact__L2ERC721Bridge from '@eth-optimism/contracts-periphery/artifacts/contracts/L2/L2ERC721Bridge.sol/L2ERC721Bridge.json'
import Artifact__OptimismMintableERC721Factory from '@eth-optimism/contracts-periphery/artifacts/contracts/universal/op-erc721/OptimismMintableERC721Factory.sol/OptimismMintableERC721Factory.json'
import Artifact__OptimismMintableERC721 from '@eth-optimism/contracts-periphery/artifacts/contracts/universal/op-erc721/OptimismMintableERC721.sol/OptimismMintableERC721.json'
......
# Changelog
## 0.5.23
### Patch Changes
- c3363225: fix NPE in debug_standardTraceBlockToFile
## 0.5.22
### Patch Changes
......
{
"name": "@eth-optimism/l2geth",
"version": "0.5.22",
"version": "0.5.23",
"private": true,
"devDependencies": {}
}
......@@ -2,6 +2,8 @@ FROM golang:1.18.0-alpine3.15 as builder
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
# build op-batcher with local monorepo go modules
COPY ./op-batcher/docker.go.work /app/go.work
COPY ./op-bindings /app/op-bindings
COPY ./op-node /app/op-node
COPY ./op-proposer /app/op-proposer
......
go 1.18
use (
./op-batcher
./op-bindings
./op-node
./op-proposer
)
......@@ -3,8 +3,8 @@ module github.com/ethereum-optimism/optimism/op-batcher
go 1.18
require (
github.com/ethereum-optimism/optimism/op-node v0.0.0
github.com/ethereum-optimism/optimism/op-proposer v0.0.0
github.com/ethereum-optimism/optimism/op-node v0.3.0
github.com/ethereum-optimism/optimism/op-proposer v0.3.0
github.com/ethereum/go-ethereum v1.10.17
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/urfave/cli v1.22.5
......@@ -21,7 +21,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/ethereum-optimism/optimism/op-bindings v0.0.0 // indirect
github.com/ethereum-optimism/optimism/op-bindings v0.3.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
......@@ -54,10 +54,4 @@ require (
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
)
replace (
github.com/ethereum-optimism/optimism/op-bindings v0.0.0 => ../op-bindings
github.com/ethereum-optimism/optimism/op-node v0.0.0 => ../op-node
github.com/ethereum-optimism/optimism/op-proposer v0.0.0 => ../op-proposer
)
replace github.com/ethereum/go-ethereum v1.10.17 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d
......@@ -161,6 +161,12 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/optimism/op-bindings v0.0.0-20220614233543-0d8fa52afca2/go.mod h1:e9mMYiVsdJf9BI//FdaA77BwNNgNMR043JtB7CPXNxY=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0 h1:d2Mwb8FzR2zuhW0sS5xFKWz/6VFPTEIE+XINqZj0Rv4=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0/go.mod h1:CrvUVIISKcyJ7o27ub/HY4Kq9wEJQxrGmWthTqxPSGo=
github.com/ethereum-optimism/optimism/op-node v0.3.0 h1:jep/cbIbP7fjBSAR48yk5NJVEoGYvoNlYI00KpBI6Mw=
github.com/ethereum-optimism/optimism/op-node v0.3.0/go.mod h1:iF9AhYjr8jNeoCDNP/Vs/ywQ2USZU5L66AxZbSAUi0E=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0 h1:K1ipZt3TLD0BJi7tKOmx8tCLXj9i4f4baBIhbPmUxk4=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0/go.mod h1:GcQ9VCWz2zEVexecq5IYo/2eadK/y7IBOEfx4YV1QJk=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d h1:AYFFbxrz7kLyFbvNHGhUPZQT8KnN1PPjCj4oAcgaVCk=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d/go.mod h1:8AfU1epKggKxDt9wr7rH5KmCeiT3yT0sEvroru1mO6Q=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
......
......@@ -39,7 +39,7 @@ type HashingOutputRootProof struct {
// OptimismPortalMetaData contains all meta data concerning the OptimismPortal contract.
var OptimismPortalMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"_l2Oracle\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_finalizationPeriodSeconds\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"mint\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"gasLimit\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isCreation\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"withdrawalHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"WithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_FEE_MAX_CHANGE_DENOMINATOR\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ELASTICITY_MULTIPLIER\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIAL_BASE_FEE\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"L2_ORACLE\",\"outputs\":[{\"internalType\":\"contractL2OutputOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAJOR_VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"MINOR_VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PATCH_VERSION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":[{\"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\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"version\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"withdrawerStorageRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"latestBlockhash\",\"type\":\"bytes32\"}],\"internalType\":\"structHashing.OutputRootProof\",\"name\":\"_outputRootProof\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"_withdrawalProof\",\"type\":\"bytes\"}],\"name\":\"finalizeWithdrawalTransaction\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"finalizedWithdrawals\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_l2BlockNumber\",\"type\":\"uint256\"}],\"name\":\"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\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
Bin: "0x6101206040523480156200001257600080fd5b5060405162003f2b38038062003f2b833981016040819052620000359162000285565b60008060016200007460408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b60809290925260a05260c0526001600160a01b0382166101005260e08190526200009d620000a5565b5050620002c1565b6000620000b3600162000164565b90508015620000cc576000805461ff0019166101001790555b603380546001600160a01b03191661dead1790556200011a60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b801562000161576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b60008054610100900460ff1615620001fd578160ff1660011480156200019d57506200019b306200027660201b620014801760201c565b155b620001f55760405162461bcd60e51b815260206004820152602e602482015260008051602062003f0b83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b506000919050565b60005460ff8084169116106200025c5760405162461bcd60e51b815260206004820152602e602482015260008051602062003f0b83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620001ec565b506000805460ff191660ff92909216919091179055600190565b6001600160a01b03163b151590565b600080604083850312156200029957600080fd5b82516001600160a01b0381168114620002b157600080fd5b6020939093015192949293505050565b60805160a05160c05160e05161010051613bd4620003376000396000818161016a0152818161099101528181610a0801528181610a9b01528181610b6d0152610f0a01526000818161044c01528181610c1f0152610f8d0152600061023b01526000610327015260006104800152613bd46000f3fe60806040526004361061012c5760003560e01c8063a14238e7116100a5578063cff0ab9611610074578063eecf1c3611610059578063eecf1c3614610427578063f4daa2911461043a578063f786becd1461046e57600080fd5b8063cff0ab9614610373578063e9e05c421461041457600080fd5b8063a14238e7146102e5578063c8b9153114610315578063ca3e99ba14610349578063cd7c97891461035e57600080fd5b80636bf2606a116100fc5780638129fc1c116100e15780638129fc1c1461028d578063867ead13146102a25780639bf62d82146102b857600080fd5b80636bf2606a146102295780636dbffb781461025d57600080fd5b80621c2ff61461015857806313620abd146101b657806364b79208146101ef5780636bb0291e1461021457600080fd5b36610153576101513334620186a06000604051806020016040528060008152506104a2565b005b600080fd5b34801561016457600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c257600080fd5b506101ce633b9aca0081565b6040516fffffffffffffffffffffffffffffffff90911681526020016101ad565b3480156101fb57600080fd5b50610206627a120081565b6040519081526020016101ad565b34801561022057600080fd5b50610206600481565b34801561023557600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561026957600080fd5b5061027d6102783660046132bd565b610948565b60405190151581526020016101ad565b34801561029957600080fd5b50610151610c56565b3480156102ae57600080fd5b5061020661271081565b3480156102c457600080fd5b5060335461018c9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102f157600080fd5b5061027d6103003660046132bd565b60346020526000908152604090205460ff1681565b34801561032157600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561035557600080fd5b50610206610d78565b34801561036a57600080fd5b50610206600881565b34801561037f57600080fd5b506001546103db906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101ad565b610151610422366004613378565b6104a2565b6101516104353660046134c2565b610d89565b34801561044657600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561047a57600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156105595773ffffffffffffffffffffffffffffffffffffffff87161561055957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b3332811461057a575033731111000000000000000000000000000000001111015b8773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f78231ae6eb73366f912bb1d64351601fb76344c537bbab635ce14d0f376f0195348a8a8a8a6040516105df95949392919061362d565b60405180910390a35060015460009061061e907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643613693565b905080156107a75760006106366004627a12006136d9565b6001546106619190700100000000000000000000000000000000900467ffffffffffffffff16613741565b9050600060086106756004627a12006136d9565b6001546106959085906fffffffffffffffffffffffffffffffff166137b5565b61069f91906136d9565b6106a991906136d9565b6001549091506000906106f5906106df906106d79085906fffffffffffffffffffffffffffffffff16613871565b61271061149c565b6fffffffffffffffffffffffffffffffff6114b7565b90506001841115610768576107656106df670de0b6b3a764000061075161071d6008836136d9565b61072f90670de0b6b3a7640000613741565b61073a60018a613693565b61074c90670de0b6b3a76400006138e5565b6114c6565b61075b90856137b5565b6106d791906136d9565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548491906010906107da908490700100000000000000000000000000000000900467ffffffffffffffff16613922565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156108b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4f7074696d69736d506f7274616c3a2063616e6e6f7420627579206d6f72652060448201527f676173207468616e20617661696c61626c6520676173206c696d6974000000006064820152608401610550565b6001546000906108e2906fffffffffffffffffffffffffffffffff1667ffffffffffffffff861661394e565b6fffffffffffffffffffffffffffffffff169050600061090648633b9aca006114f7565b6109109083613986565b905060005a61091f9086613693565b90508082111561093b5761093b6109368284613693565b611507565b5050505050505050505050565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa1580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fb919061399a565b8051909150610c1d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663529933df6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9591906139e9565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634ab65d736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2891906139e9565b905084811115610b3d57506000949350505050565b600082610b4a8388613693565b610b549190613a02565b905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae557610b9c8386613693565b610ba69089613a16565b6040518263ffffffff1660e01b8152600401610bc491815260200190565b6040805180830381865afa158015610be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c04919061399a565b8051909450610c195750600095945050505050565b5050505b7f00000000000000000000000000000000000000000000000000000000000000008160200151610c4d9190613a16565b42119392505050565b6000610c626001611535565b90508015610c9757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055610d1260408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b8015610d7557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b610d866004627a12006136d9565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610e32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610550565b73ffffffffffffffffffffffffffffffffffffffff8916301415610ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610550565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f89919061399a565b90507f00000000000000000000000000000000000000000000000000000000000000008160200151610fbb9190613a16565b4211611049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a6564000000000000000000000000000000000000006064820152608401610550565b61106061105b36869003860186613a2e565b6116c0565b8151146110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610550565b60006111358d8d8d8d8d8d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061171c92505050565b905061117c81866040013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b611208576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610550565b60008181526034602052604090205460ff16156112a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610550565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556112ea614e208a613a16565b5a1015611379576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610550565b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8e16179055604080516020601f8a01819004810282018101909252888152600091611402918e918d918f918691908f908f908190840183828082843760009201919091525061182492505050565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061146890841515815260200190565b60405180910390a25050505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156114ac57816114ae565b825b90505b92915050565b60008183126114ac57816114ae565b60006114ae670de0b6b3a7640000836114de866118af565b6114e891906137b5565b6114f291906136d9565b611af3565b6000818310156114ac57816114ae565b6000805a90505b825a61151a9083613693565b10156115305761152982613a94565b915061150e565b505050565b60008054610100900460ff16156115ec578160ff1660011480156115585750303b155b6115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b506000919050565b60005460ff808416911610611683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600081600001518260200151836040015184606001516040516020016116ff949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b600086868686868660405160200161173996959493929190613acd565b6040516020818303038152906040528051906020012090509695505050505050565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506118199101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611d32565b9150505b9392505050565b6000606060008060008661ffff1667ffffffffffffffff81111561184a5761184a6132fa565b6040519080825280601f01601f191660200182016040528015611874576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611895578692505b828152826000602083013e90999098509650505050505050565b600080821361191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b6000606061192784611d56565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213611b2457506000919050565b680755bf798b4a1bf1e58212611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610550565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611d3e86611e2c565b9050611d4c81868686611e5e565b9695505050505050565b6000808211611dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611e4891815260200190565b6040516020818303038152906040529050919050565b6000806000611e6e878686611e9b565b91509150818015611e9057508051602080830191909120875191880191909120145b979650505050505050565b600060606000611eaa85611f90565b90506000806000611ebc848a8961208b565b81519295509093509150158080611ed05750815b611f36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f50726f76696465642070726f6f6620697320696e76616c69642e0000000000006044820152606401610550565b600081611f525760405180602001604052806000815250611f7e565b611f7e86611f61600188613693565b81518110611f7157611f71613b24565b60200260200101516125a8565b919b919a509098505050505050505050565b60606000611f9d836125d2565b90506000815167ffffffffffffffff811115611fbb57611fbb6132fa565b60405190808252806020026020018201604052801561200057816020015b6040805180820190915260608082526020820152815260200190600190039081611fd95790505b50905060005b825181101561208357600061203384838151811061202657612026613b24565b6020026020010151612605565b9050604051806040016040528082815260200161204f836125d2565b81525083838151811061206457612064613b24565b602002602001018190525050808061207b90613a94565b915050612006565b509392505050565b6000606081808061209b876126af565b905060008690506000806120c2604051806040016040528060608152602001606081525090565b60005b8c51811015612564578c81815181106120e0576120e0613b24565b6020026020010151915082846120f69190613a16565b9350612103600188613a16565b9650836121815781518051602090910120851461217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c696420726f6f7420686173680000000000000000000000000000006044820152606401610550565b612272565b8151516020116121fd5781518051602090910120851461217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206c6172676520696e7465726e616c206861736800000000006044820152606401610550565b8461220b8360000151612832565b14612272576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c696420696e7465726e616c206e6f646520686173680000000000006044820152606401610550565b61227e60106001613a16565b82602001515114156122f757855184141561229857612564565b60008685815181106122ac576122ac613b24565b602001015160f81c60f81b60f81c9050600083602001518260ff16815181106122d7576122d7613b24565b602002602001015190506122ea8161285a565b9650600194505050612552565b600282602001515114156124f057600061231083612890565b905060008160008151811061232757612327613b24565b016020015160f81c9050600061233e600283613b53565b612349906002613b75565b9050600061235a848360ff166128b4565b905060006123688b8a6128b4565b9050600061237683836128ea565b905060ff85166002148061238d575060ff85166003145b156123e3578083511480156123a25750808251145b156123b4576123b1818b613a16565b99505b507f80000000000000000000000000000000000000000000000000000000000000009950612564945050505050565b60ff851615806123f6575060ff85166001145b15612468578251811461243257507f80000000000000000000000000000000000000000000000000000000000000009950612564945050505050565b612459886020015160018151811061244c5761244c613b24565b602002602001015161285a565b9a509750612552945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f52656365697665642061206e6f6465207769746820616e20756e6b6e6f776e2060448201527f70726566697800000000000000000000000000000000000000000000000000006064820152608401610550565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f526563656976656420616e20756e706172736561626c65206e6f64652e0000006044820152606401610550565b8061255c81613a94565b9150506120c5565b507f800000000000000000000000000000000000000000000000000000000000000084148661259387866128b4565b909e909d50909b509950505050505050505050565b602081015180516060916114b1916125c290600190613693565b8151811061202657612026613b24565b6040805180820182526000808252602091820152815180830190925282518252808301908201526060906114b190612996565b6060600080600061261585612bc9565b91945092509050600081600181111561263057612630613b98565b14612697576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c502062797465732076616c75652e00000000000000006044820152606401610550565b6126a685602001518484612fd0565b95945050505050565b60606000825160026126c191906138e5565b67ffffffffffffffff8111156126d9576126d96132fa565b6040519080825280601f01601f191660200182016040528015612703576020820181803683370190505b50905060005b835181101561282b57600484828151811061272657612726613b24565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c8261275b8360026138e5565b8151811061276b5761276b613b24565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060108482815181106127ae576127ae613b24565b01602001516127c0919060f81c613b53565b60f81b826127cf8360026138e5565b6127da906001613a16565b815181106127ea576127ea613b24565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061282381613a94565b915050612709565b5092915050565b600060208251101561284657506020015190565b818060200190518101906114b191906139e9565b6000606060208360000151101561287b57612874836130af565b9050612887565b61288483612605565b90505b61181d81612832565b60606114b16128af836020015160008151811061202657612026613b24565b6126af565b6060825182106128d357506040805160208101909152600081526114b1565b6114ae83838486516128e59190613693565b6130ba565b6000805b8084511180156128fe5750808351115b801561297f575082818151811061291757612917613b24565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811061295657612956613b24565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156114ae578061298e81613a94565b9150506128ee565b60606000806129a484612bc9565b919350909150600190508160018111156129c0576129c0613b98565b14612a27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c50206c6973742076616c75652e0000000000000000006044820152606401610550565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a405790505090506000835b8651811015612bbe5760208210612b06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50726f766964656420524c50206c6973742065786365656473206d6178206c6960448201527f7374206c656e6774682e000000000000000000000000000000000000000000006064820152608401610550565b600080612b436040518060400160405280858c60000151612b279190613693565b8152602001858c60200151612b3c9190613a16565b9052612bc9565b509150915060405180604001604052808383612b5f9190613a16565b8152602001848b60200151612b749190613a16565b815250858581518110612b8957612b89613b24565b6020908102919091010152612b9f600185613a16565b9350612bab8183613a16565b612bb59084613a16565b92505050612a6d565b508152949350505050565b600080600080846000015111612c3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f524c50206974656d2063616e6e6f74206265206e756c6c2e00000000000000006044820152606401610550565b6020840151805160001a607f8111612c60576000600160009450945094505050612fc9565b60b78111612cf6576000612c75608083613693565b905080876000015111612ce4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e76616c696420524c502073686f727420737472696e672e000000000000006044820152606401610550565b60019550935060009250612fc9915050565b60bf8111612e19576000612d0b60b783613693565b905080876000015111612d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f496e76616c696420524c50206c6f6e6720737472696e67206c656e6774682e006044820152606401610550565b600183015160208290036101000a9004612d948183613a16565b885111612dfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c50206c6f6e6720737472696e672e00000000000000006044820152606401610550565b612e08826001613a16565b9650945060009350612fc992505050565b60f78111612eae576000612e2e60c083613693565b905080876000015111612e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c502073686f7274206c6973742e0000000000000000006044820152606401610550565b600195509350849250612fc9915050565b6000612ebb60f783613693565b905080876000015111612f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c696420524c50206c6f6e67206c697374206c656e6774682e0000006044820152606401610550565b600183015160208290036101000a9004612f448183613a16565b885111612fad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420524c50206c6f6e67206c6973742e000000000000000000006044820152606401610550565b612fb8826001613a16565b9650945060019350612fc992505050565b9193909250565b606060008267ffffffffffffffff811115612fed57612fed6132fa565b6040519080825280601f01601f191660200182016040528015613017576020820181803683370190505b50905080516000141561302b57905061181d565b60006130378587613a16565b90506020820160005b61304b602087613986565b8110156130825782518252613061602084613a16565b925061306e602083613a16565b91508061307a81613a94565b915050613040565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b60606114b1826132a7565b6060816130c881601f613a16565b1015613130576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b8261313b8382613a16565b10156131a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b6131ad8284613a16565b84511015613217576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610550565b606082158015613236576040519150600082526020820160405261329e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561326f578051835260209283019201613257565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60606114b1826020015160008460000151612fd0565b6000602082840312156132cf57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146116bb57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613370576133706132fa565b604052919050565b600080600080600060a0868803121561339057600080fd5b613399866132d6565b94506020808701359450604087013567ffffffffffffffff80821682146133bf57600080fd5b90945060608801359081151582146133d657600080fd5b909350608088013590808211156133ec57600080fd5b818901915089601f83011261340057600080fd5b813581811115613412576134126132fa565b613442847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613329565b91508082528a8482850101111561345857600080fd5b80848401858401376000848284010152508093505050509295509295909350565b60008083601f84011261348b57600080fd5b50813567ffffffffffffffff8111156134a357600080fd5b6020830191508360208285010111156134bb57600080fd5b9250929050565b60008060008060008060008060008060006101808c8e0312156134e457600080fd5b8b359a506134f460208d016132d6565b995061350260408d016132d6565b985060608c0135975060808c0135965067ffffffffffffffff60a08d0135111561352b57600080fd5b61353b8d60a08e01358e01613479565b909650945060c08c0135935060808c8e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2001121561357957600080fd5b60e08c01925067ffffffffffffffff6101608d0135111561359957600080fd5b6135aa8d6101608e01358e01613479565b81935080925050509295989b509295989b9093969950565b6000815180845260005b818110156135e8576020818501810151868301820152016135cc565b818111156135fa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b85815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611e9060a08301846135c2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156136a5576136a5613664565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826136e8576136e86136aa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561373c5761373c613664565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561377b5761377b613664565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156137af576137af613664565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156137f6576137f6613664565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561383157613831613664565b6000871292508782058712848416161561384d5761384d613664565b8785058712818416161561386357613863613664565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156138ab576138ab613664565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156138df576138df613664565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561391d5761391d613664565b500290565b600067ffffffffffffffff80831681851680830382111561394557613945613664565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561397d5761397d613664565b02949350505050565b600082613995576139956136aa565b500490565b6000604082840312156139ac57600080fd5b6040516040810181811067ffffffffffffffff821117156139cf576139cf6132fa565b604052825181526020928301519281019290925250919050565b6000602082840312156139fb57600080fd5b5051919050565b600082613a1157613a116136aa565b500690565b60008219821115613a2957613a29613664565b500190565b600060808284031215613a4057600080fd5b6040516080810181811067ffffffffffffffff82111715613a6357613a636132fa565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613ac657613ac6613664565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613b1860c08301846135c2565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680613b6657613b666136aa565b8060ff84160691505092915050565b600060ff821660ff841680821015613b8f57613b8f613664565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080a000a496e697469616c697a61626c653a20636f6e747261637420697320616c726561",
Bin: "0x6101206040523480156200001257600080fd5b5060405162003ffe38038062003ffe8339810160408190526200003591620002bc565b6000608081905260a052600160c0526001600160a01b0382166101005260e08190526200006162000069565b5050620002f8565b6000620000776001620000f8565b9050801562000090576000805461ff0019166101001790555b603380546001600160a01b03191661dead179055620000ae6200020a565b8015620000f5576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b60008054610100900460ff161562000191578160ff1660011480156200013157506200012f30620002ad60201b620014391760201c565b155b620001895760405162461bcd60e51b815260206004820152602e602482015260008051602062003fde83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b506000919050565b60005460ff808416911610620001f05760405162461bcd60e51b815260206004820152602e602482015260008051602062003fde83398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000180565b506000805460ff191660ff92909216919091179055600190565b600054610100900460ff16620002775760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162000180565b60408051606081018252633b9aca0080825260006020830152436001600160401b031691909201819052600160c01b0217600155565b6001600160a01b03163b151590565b60008060408385031215620002d057600080fd5b82516001600160a01b0381168114620002e857600080fd5b6020939093015192949293505050565b60805160a05160c05160e05161010051613c706200036e6000396000818161016a0152818161099101528181610a0801528181610a9b01528181610b6d0152610ec301526000818161044c01528181610c1f0152610f460152600061023b01526000610327015260006104800152613c706000f3fe60806040526004361061012c5760003560e01c8063a14238e7116100a5578063cff0ab9611610074578063eecf1c3611610059578063eecf1c3614610427578063f4daa2911461043a578063f786becd1461046e57600080fd5b8063cff0ab9614610373578063e9e05c421461041457600080fd5b8063a14238e7146102e5578063c8b9153114610315578063ca3e99ba14610349578063cd7c97891461035e57600080fd5b80636bf2606a116100fc5780638129fc1c116100e15780638129fc1c1461028d578063867ead13146102a25780639bf62d82146102b857600080fd5b80636bf2606a146102295780636dbffb781461025d57600080fd5b80621c2ff61461015857806313620abd146101b657806364b79208146101ef5780636bb0291e1461021457600080fd5b36610153576101513334620186a06000604051806020016040528060008152506104a2565b005b600080fd5b34801561016457600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c257600080fd5b506101ce633b9aca0081565b6040516fffffffffffffffffffffffffffffffff90911681526020016101ad565b3480156101fb57600080fd5b50610206627a120081565b6040519081526020016101ad565b34801561022057600080fd5b50610206600481565b34801561023557600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561026957600080fd5b5061027d610278366004613359565b610948565b60405190151581526020016101ad565b34801561029957600080fd5b50610151610c56565b3480156102ae57600080fd5b5061020661271081565b3480156102c457600080fd5b5060335461018c9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102f157600080fd5b5061027d610300366004613359565b60346020526000908152604090205460ff1681565b34801561032157600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561035557600080fd5b50610206610d31565b34801561036a57600080fd5b50610206600881565b34801561037f57600080fd5b506001546103db906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101ad565b610151610422366004613414565b6104a2565b61015161043536600461355e565b610d42565b34801561044657600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561047a57600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156105595773ffffffffffffffffffffffffffffffffffffffff87161561055957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b3332811461057a575033731111000000000000000000000000000000001111015b8773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f78231ae6eb73366f912bb1d64351601fb76344c537bbab635ce14d0f376f0195348a8a8a8a6040516105df9594939291906136c9565b60405180910390a35060015460009061061e907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361372f565b905080156107a75760006106366004627a1200613775565b6001546106619190700100000000000000000000000000000000900467ffffffffffffffff166137dd565b9050600060086106756004627a1200613775565b6001546106959085906fffffffffffffffffffffffffffffffff16613851565b61069f9190613775565b6106a99190613775565b6001549091506000906106f5906106df906106d79085906fffffffffffffffffffffffffffffffff1661390d565b612710611455565b6fffffffffffffffffffffffffffffffff611470565b90506001841115610768576107656106df670de0b6b3a764000061075161071d600883613775565b61072f90670de0b6b3a76400006137dd565b61073a60018a61372f565b61074c90670de0b6b3a7640000613981565b61147f565b61075b9085613851565b6106d79190613775565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548491906010906107da908490700100000000000000000000000000000000900467ffffffffffffffff166139be565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156108b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4f7074696d69736d506f7274616c3a2063616e6e6f7420627579206d6f72652060448201527f676173207468616e20617661696c61626c6520676173206c696d6974000000006064820152608401610550565b6001546000906108e2906fffffffffffffffffffffffffffffffff1667ffffffffffffffff86166139ea565b6fffffffffffffffffffffffffffffffff169050600061090648633b9aca006114b0565b6109109083613a22565b905060005a61091f908661372f565b90508082111561093b5761093b610936828461372f565b6114c0565b5050505050505050505050565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa1580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fb9190613a36565b8051909150610c1d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663529933df6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a959190613a85565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634ab65d736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b289190613a85565b905084811115610b3d57506000949350505050565b600082610b4a838861372f565b610b549190613a9e565b905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae557610b9c838661372f565b610ba69089613ab2565b6040518263ffffffff1660e01b8152600401610bc491815260200190565b6040805180830381865afa158015610be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c049190613a36565b8051909450610c195750600095945050505050565b5050505b7f00000000000000000000000000000000000000000000000000000000000000008160200151610c4d9190613ab2565b42119392505050565b6000610c6260016114ee565b90508015610c9757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055610ccb611679565b8015610d2e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b610d3f6004627a1200613775565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610550565b73ffffffffffffffffffffffffffffffffffffffff8916301415610e91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610550565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610f1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f429190613a36565b90507f00000000000000000000000000000000000000000000000000000000000000008160200151610f749190613ab2565b4211611002576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a6564000000000000000000000000000000000000006064820152608401610550565b61101961101436869003860186613aca565b61175c565b8151146110a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610550565b60006110ee8d8d8d8d8d8d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117b892505050565b905061113581866040013586868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117f792505050565b6111c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610550565b60008181526034602052604090205460ff1615611260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610550565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556112a3614e208a613ab2565b5a1015611332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610550565b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8e16179055604080516020601f8a018190048102820181019092528881526000916113bb918e918d918f918691908f908f90819084018382808284376000920191909152506118c092505050565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061142190841515815260200190565b60405180910390a25050505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156114655781611467565b825b90505b92915050565b60008183126114655781611467565b6000611467670de0b6b3a7640000836114978661194b565b6114a19190613851565b6114ab9190613775565b611b8f565b6000818310156114655781611467565b6000805a90505b825a6114d3908361372f565b10156114e9576114e282613b30565b91506114c7565b505050565b60008054610100900460ff16156115a5578160ff1660011480156115115750303b155b61159d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b506000919050565b60005460ff80841691161061163c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff16611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610550565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6000816000015182602001518360400151846060015160405160200161179b949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60008686868686866040516020016117d596959493929190613b69565b6040516020818303038152906040528051906020012090509695505050505050565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506118b59101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611dce565b9150505b9392505050565b6000606060008060008661ffff1667ffffffffffffffff8111156118e6576118e6613396565b6040519080825280601f01601f191660200182016040528015611910576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611931578692505b828152826000602083013e90999098509650505050505050565b60008082136119b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b600060606119c384611df2565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213611bc057506000919050565b680755bf798b4a1bf1e58212611c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610550565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611dda86611ec8565b9050611de881868686611efa565b9695505050505050565b6000808211611e5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611ee491815260200190565b6040516020818303038152906040529050919050565b6000806000611f0a878686611f37565b91509150818015611f2c57508051602080830191909120875191880191909120145b979650505050505050565b600060606000611f468561202c565b90506000806000611f58848a89612127565b81519295509093509150158080611f6c5750815b611fd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f50726f76696465642070726f6f6620697320696e76616c69642e0000000000006044820152606401610550565b600081611fee576040518060200160405280600081525061201a565b61201a86611ffd60018861372f565b8151811061200d5761200d613bc0565b6020026020010151612644565b919b919a509098505050505050505050565b606060006120398361266e565b90506000815167ffffffffffffffff81111561205757612057613396565b60405190808252806020026020018201604052801561209c57816020015b60408051808201909152606080825260208201528152602001906001900390816120755790505b50905060005b825181101561211f5760006120cf8483815181106120c2576120c2613bc0565b60200260200101516126a1565b905060405180604001604052808281526020016120eb8361266e565b81525083838151811061210057612100613bc0565b602002602001018190525050808061211790613b30565b9150506120a2565b509392505050565b600060608180806121378761274b565b9050600086905060008061215e604051806040016040528060608152602001606081525090565b60005b8c51811015612600578c818151811061217c5761217c613bc0565b6020026020010151915082846121929190613ab2565b935061219f600188613ab2565b96508361221d57815180516020909101208514612218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c696420726f6f7420686173680000000000000000000000000000006044820152606401610550565b61230e565b81515160201161229957815180516020909101208514612218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206c6172676520696e7465726e616c206861736800000000006044820152606401610550565b846122a783600001516128ce565b1461230e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c696420696e7465726e616c206e6f646520686173680000000000006044820152606401610550565b61231a60106001613ab2565b826020015151141561239357855184141561233457612600565b600086858151811061234857612348613bc0565b602001015160f81c60f81b60f81c9050600083602001518260ff168151811061237357612373613bc0565b60200260200101519050612386816128f6565b96506001945050506125ee565b6002826020015151141561258c5760006123ac8361292c565b90506000816000815181106123c3576123c3613bc0565b016020015160f81c905060006123da600283613bef565b6123e5906002613c11565b905060006123f6848360ff16612950565b905060006124048b8a612950565b905060006124128383612986565b905060ff851660021480612429575060ff85166003145b1561247f5780835114801561243e5750808251145b156124505761244d818b613ab2565b99505b507f80000000000000000000000000000000000000000000000000000000000000009950612600945050505050565b60ff85161580612492575060ff85166001145b1561250457825181146124ce57507f80000000000000000000000000000000000000000000000000000000000000009950612600945050505050565b6124f588602001516001815181106124e8576124e8613bc0565b60200260200101516128f6565b9a5097506125ee945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f52656365697665642061206e6f6465207769746820616e20756e6b6e6f776e2060448201527f70726566697800000000000000000000000000000000000000000000000000006064820152608401610550565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f526563656976656420616e20756e706172736561626c65206e6f64652e0000006044820152606401610550565b806125f881613b30565b915050612161565b507f800000000000000000000000000000000000000000000000000000000000000084148661262f8786612950565b909e909d50909b509950505050505050505050565b6020810151805160609161146a9161265e9060019061372f565b815181106120c2576120c2613bc0565b60408051808201825260008082526020918201528151808301909252825182528083019082015260609061146a90612a32565b606060008060006126b185612c65565b9194509250905060008160018111156126cc576126cc613c34565b14612733576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c502062797465732076616c75652e00000000000000006044820152606401610550565b6127428560200151848461306c565b95945050505050565b606060008251600261275d9190613981565b67ffffffffffffffff81111561277557612775613396565b6040519080825280601f01601f19166020018201604052801561279f576020820181803683370190505b50905060005b83518110156128c75760048482815181106127c2576127c2613bc0565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c826127f7836002613981565b8151811061280757612807613bc0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350601084828151811061284a5761284a613bc0565b016020015161285c919060f81c613bef565b60f81b8261286b836002613981565b612876906001613ab2565b8151811061288657612886613bc0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806128bf81613b30565b9150506127a5565b5092915050565b60006020825110156128e257506020015190565b8180602001905181019061146a9190613a85565b60006060602083600001511015612917576129108361314b565b9050612923565b612920836126a1565b90505b6118b9816128ce565b606061146a61294b83602001516000815181106120c2576120c2613bc0565b61274b565b60608251821061296f575060408051602081019091526000815261146a565b6114678383848651612981919061372f565b613156565b6000805b80845111801561299a5750808351115b8015612a1b57508281815181106129b3576129b3613bc0565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168482815181106129f2576129f2613bc0565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156114675780612a2a81613b30565b91505061298a565b6060600080612a4084612c65565b91935090915060019050816001811115612a5c57612a5c613c34565b14612ac3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c50206c6973742076616c75652e0000000000000000006044820152606401610550565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612adc5790505090506000835b8651811015612c5a5760208210612ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50726f766964656420524c50206c6973742065786365656473206d6178206c6960448201527f7374206c656e6774682e000000000000000000000000000000000000000000006064820152608401610550565b600080612bdf6040518060400160405280858c60000151612bc3919061372f565b8152602001858c60200151612bd89190613ab2565b9052612c65565b509150915060405180604001604052808383612bfb9190613ab2565b8152602001848b60200151612c109190613ab2565b815250858581518110612c2557612c25613bc0565b6020908102919091010152612c3b600185613ab2565b9350612c478183613ab2565b612c519084613ab2565b92505050612b09565b508152949350505050565b600080600080846000015111612cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f524c50206974656d2063616e6e6f74206265206e756c6c2e00000000000000006044820152606401610550565b6020840151805160001a607f8111612cfc576000600160009450945094505050613065565b60b78111612d92576000612d1160808361372f565b905080876000015111612d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e76616c696420524c502073686f727420737472696e672e000000000000006044820152606401610550565b60019550935060009250613065915050565b60bf8111612eb5576000612da760b78361372f565b905080876000015111612e16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f496e76616c696420524c50206c6f6e6720737472696e67206c656e6774682e006044820152606401610550565b600183015160208290036101000a9004612e308183613ab2565b885111612e99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c50206c6f6e6720737472696e672e00000000000000006044820152606401610550565b612ea4826001613ab2565b965094506000935061306592505050565b60f78111612f4a576000612eca60c08361372f565b905080876000015111612f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c502073686f7274206c6973742e0000000000000000006044820152606401610550565b600195509350849250613065915050565b6000612f5760f78361372f565b905080876000015111612fc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c696420524c50206c6f6e67206c697374206c656e6774682e0000006044820152606401610550565b600183015160208290036101000a9004612fe08183613ab2565b885111613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420524c50206c6f6e67206c6973742e000000000000000000006044820152606401610550565b613054826001613ab2565b965094506001935061306592505050565b9193909250565b606060008267ffffffffffffffff81111561308957613089613396565b6040519080825280601f01601f1916602001820160405280156130b3576020820181803683370190505b5090508051600014156130c75790506118b9565b60006130d38587613ab2565b90506020820160005b6130e7602087613a22565b81101561311e57825182526130fd602084613ab2565b925061310a602083613ab2565b91508061311681613b30565b9150506130dc565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b606061146a82613343565b60608161316481601f613ab2565b10156131cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b826131d78382613ab2565b101561323f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b6132498284613ab2565b845110156132b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610550565b6060821580156132d2576040519150600082526020820160405261333a565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561330b5780518352602092830192016132f3565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b606061146a82602001516000846000015161306c565b60006020828403121561336b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561340c5761340c613396565b604052919050565b600080600080600060a0868803121561342c57600080fd5b61343586613372565b94506020808701359450604087013567ffffffffffffffff808216821461345b57600080fd5b909450606088013590811515821461347257600080fd5b9093506080880135908082111561348857600080fd5b818901915089601f83011261349c57600080fd5b8135818111156134ae576134ae613396565b6134de847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016133c5565b91508082528a848285010111156134f457600080fd5b80848401858401376000848284010152508093505050509295509295909350565b60008083601f84011261352757600080fd5b50813567ffffffffffffffff81111561353f57600080fd5b60208301915083602082850101111561355757600080fd5b9250929050565b60008060008060008060008060008060006101808c8e03121561358057600080fd5b8b359a5061359060208d01613372565b995061359e60408d01613372565b985060608c0135975060808c0135965067ffffffffffffffff60a08d013511156135c757600080fd5b6135d78d60a08e01358e01613515565b909650945060c08c0135935060808c8e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2001121561361557600080fd5b60e08c01925067ffffffffffffffff6101608d0135111561363557600080fd5b6136468d6101608e01358e01613515565b81935080925050509295989b509295989b9093969950565b6000815180845260005b8181101561368457602081850181015186830182015201613668565b81811115613696576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b85815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611f2c60a083018461365e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561374157613741613700565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261378457613784613746565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156137d8576137d8613700565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561381757613817613700565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561384b5761384b613700565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561389257613892613700565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156138cd576138cd613700565b600087129250878205871284841616156138e9576138e9613700565b878505871281841616156138ff576138ff613700565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561394757613947613700565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561397b5761397b613700565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156139b9576139b9613700565b500290565b600067ffffffffffffffff8083168185168083038211156139e1576139e1613700565b01949350505050565b60006fffffffffffffffffffffffffffffffff80831681851681830481118215151615613a1957613a19613700565b02949350505050565b600082613a3157613a31613746565b500490565b600060408284031215613a4857600080fd5b6040516040810181811067ffffffffffffffff82111715613a6b57613a6b613396565b604052825181526020928301519281019290925250919050565b600060208284031215613a9757600080fd5b5051919050565b600082613aad57613aad613746565b500690565b60008219821115613ac557613ac5613700565b500190565b600060808284031215613adc57600080fd5b6040516080810181811067ffffffffffffffff82111715613aff57613aff613396565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613b6257613b62613700565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613bb460c083018461365e565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680613c0257613c02613746565b8060ff84160691505092915050565b600060ff821660ff841680821015613c2b57613c2b613700565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080a000a496e697469616c697a61626c653a20636f6e747261637420697320616c726561",
}
// OptimismPortalABI is the input ABI used to generate the binding from.
......
......@@ -2,4 +2,4 @@
// This file is a generated binding and any manual changes will be lost.
package bindings
var OptimismPortalDeployedBin = "0x60806040526004361061012c5760003560e01c8063a14238e7116100a5578063cff0ab9611610074578063eecf1c3611610059578063eecf1c3614610427578063f4daa2911461043a578063f786becd1461046e57600080fd5b8063cff0ab9614610373578063e9e05c421461041457600080fd5b8063a14238e7146102e5578063c8b9153114610315578063ca3e99ba14610349578063cd7c97891461035e57600080fd5b80636bf2606a116100fc5780638129fc1c116100e15780638129fc1c1461028d578063867ead13146102a25780639bf62d82146102b857600080fd5b80636bf2606a146102295780636dbffb781461025d57600080fd5b80621c2ff61461015857806313620abd146101b657806364b79208146101ef5780636bb0291e1461021457600080fd5b36610153576101513334620186a06000604051806020016040528060008152506104a2565b005b600080fd5b34801561016457600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c257600080fd5b506101ce633b9aca0081565b6040516fffffffffffffffffffffffffffffffff90911681526020016101ad565b3480156101fb57600080fd5b50610206627a120081565b6040519081526020016101ad565b34801561022057600080fd5b50610206600481565b34801561023557600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561026957600080fd5b5061027d6102783660046132bd565b610948565b60405190151581526020016101ad565b34801561029957600080fd5b50610151610c56565b3480156102ae57600080fd5b5061020661271081565b3480156102c457600080fd5b5060335461018c9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102f157600080fd5b5061027d6103003660046132bd565b60346020526000908152604090205460ff1681565b34801561032157600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561035557600080fd5b50610206610d78565b34801561036a57600080fd5b50610206600881565b34801561037f57600080fd5b506001546103db906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101ad565b610151610422366004613378565b6104a2565b6101516104353660046134c2565b610d89565b34801561044657600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561047a57600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156105595773ffffffffffffffffffffffffffffffffffffffff87161561055957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b3332811461057a575033731111000000000000000000000000000000001111015b8773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f78231ae6eb73366f912bb1d64351601fb76344c537bbab635ce14d0f376f0195348a8a8a8a6040516105df95949392919061362d565b60405180910390a35060015460009061061e907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1643613693565b905080156107a75760006106366004627a12006136d9565b6001546106619190700100000000000000000000000000000000900467ffffffffffffffff16613741565b9050600060086106756004627a12006136d9565b6001546106959085906fffffffffffffffffffffffffffffffff166137b5565b61069f91906136d9565b6106a991906136d9565b6001549091506000906106f5906106df906106d79085906fffffffffffffffffffffffffffffffff16613871565b61271061149c565b6fffffffffffffffffffffffffffffffff6114b7565b90506001841115610768576107656106df670de0b6b3a764000061075161071d6008836136d9565b61072f90670de0b6b3a7640000613741565b61073a60018a613693565b61074c90670de0b6b3a76400006138e5565b6114c6565b61075b90856137b5565b6106d791906136d9565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548491906010906107da908490700100000000000000000000000000000000900467ffffffffffffffff16613922565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156108b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4f7074696d69736d506f7274616c3a2063616e6e6f7420627579206d6f72652060448201527f676173207468616e20617661696c61626c6520676173206c696d6974000000006064820152608401610550565b6001546000906108e2906fffffffffffffffffffffffffffffffff1667ffffffffffffffff861661394e565b6fffffffffffffffffffffffffffffffff169050600061090648633b9aca006114f7565b6109109083613986565b905060005a61091f9086613693565b90508082111561093b5761093b6109368284613693565b611507565b5050505050505050505050565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa1580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fb919061399a565b8051909150610c1d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663529933df6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9591906139e9565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634ab65d736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2891906139e9565b905084811115610b3d57506000949350505050565b600082610b4a8388613693565b610b549190613a02565b905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae557610b9c8386613693565b610ba69089613a16565b6040518263ffffffff1660e01b8152600401610bc491815260200190565b6040805180830381865afa158015610be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c04919061399a565b8051909450610c195750600095945050505050565b5050505b7f00000000000000000000000000000000000000000000000000000000000000008160200151610c4d9190613a16565b42119392505050565b6000610c626001611535565b90508015610c9757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055610d1260408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b8015610d7557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b610d866004627a12006136d9565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610e32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610550565b73ffffffffffffffffffffffffffffffffffffffff8916301415610ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610550565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610f65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f89919061399a565b90507f00000000000000000000000000000000000000000000000000000000000000008160200151610fbb9190613a16565b4211611049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a6564000000000000000000000000000000000000006064820152608401610550565b61106061105b36869003860186613a2e565b6116c0565b8151146110ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610550565b60006111358d8d8d8d8d8d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061171c92505050565b905061117c81866040013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061175b92505050565b611208576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610550565b60008181526034602052604090205460ff16156112a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610550565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556112ea614e208a613a16565b5a1015611379576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610550565b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8e16179055604080516020601f8a01819004810282018101909252888152600091611402918e918d918f918691908f908f908190840183828082843760009201919091525061182492505050565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061146890841515815260200190565b60405180910390a25050505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156114ac57816114ae565b825b90505b92915050565b60008183126114ac57816114ae565b60006114ae670de0b6b3a7640000836114de866118af565b6114e891906137b5565b6114f291906136d9565b611af3565b6000818310156114ac57816114ae565b6000805a90505b825a61151a9083613693565b10156115305761152982613a94565b915061150e565b505050565b60008054610100900460ff16156115ec578160ff1660011480156115585750303b155b6115e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b506000919050565b60005460ff808416911610611683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600081600001518260200151836040015184606001516040516020016116ff949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b600086868686868660405160200161173996959493929190613acd565b6040516020818303038152906040528051906020012090509695505050505050565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506118199101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611d32565b9150505b9392505050565b6000606060008060008661ffff1667ffffffffffffffff81111561184a5761184a6132fa565b6040519080825280601f01601f191660200182016040528015611874576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611895578692505b828152826000602083013e90999098509650505050505050565b600080821361191a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b6000606061192784611d56565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213611b2457506000919050565b680755bf798b4a1bf1e58212611b96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610550565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611d3e86611e2c565b9050611d4c81868686611e5e565b9695505050505050565b6000808211611dc1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611e4891815260200190565b6040516020818303038152906040529050919050565b6000806000611e6e878686611e9b565b91509150818015611e9057508051602080830191909120875191880191909120145b979650505050505050565b600060606000611eaa85611f90565b90506000806000611ebc848a8961208b565b81519295509093509150158080611ed05750815b611f36576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f50726f76696465642070726f6f6620697320696e76616c69642e0000000000006044820152606401610550565b600081611f525760405180602001604052806000815250611f7e565b611f7e86611f61600188613693565b81518110611f7157611f71613b24565b60200260200101516125a8565b919b919a509098505050505050505050565b60606000611f9d836125d2565b90506000815167ffffffffffffffff811115611fbb57611fbb6132fa565b60405190808252806020026020018201604052801561200057816020015b6040805180820190915260608082526020820152815260200190600190039081611fd95790505b50905060005b825181101561208357600061203384838151811061202657612026613b24565b6020026020010151612605565b9050604051806040016040528082815260200161204f836125d2565b81525083838151811061206457612064613b24565b602002602001018190525050808061207b90613a94565b915050612006565b509392505050565b6000606081808061209b876126af565b905060008690506000806120c2604051806040016040528060608152602001606081525090565b60005b8c51811015612564578c81815181106120e0576120e0613b24565b6020026020010151915082846120f69190613a16565b9350612103600188613a16565b9650836121815781518051602090910120851461217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c696420726f6f7420686173680000000000000000000000000000006044820152606401610550565b612272565b8151516020116121fd5781518051602090910120851461217c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206c6172676520696e7465726e616c206861736800000000006044820152606401610550565b8461220b8360000151612832565b14612272576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c696420696e7465726e616c206e6f646520686173680000000000006044820152606401610550565b61227e60106001613a16565b82602001515114156122f757855184141561229857612564565b60008685815181106122ac576122ac613b24565b602001015160f81c60f81b60f81c9050600083602001518260ff16815181106122d7576122d7613b24565b602002602001015190506122ea8161285a565b9650600194505050612552565b600282602001515114156124f057600061231083612890565b905060008160008151811061232757612327613b24565b016020015160f81c9050600061233e600283613b53565b612349906002613b75565b9050600061235a848360ff166128b4565b905060006123688b8a6128b4565b9050600061237683836128ea565b905060ff85166002148061238d575060ff85166003145b156123e3578083511480156123a25750808251145b156123b4576123b1818b613a16565b99505b507f80000000000000000000000000000000000000000000000000000000000000009950612564945050505050565b60ff851615806123f6575060ff85166001145b15612468578251811461243257507f80000000000000000000000000000000000000000000000000000000000000009950612564945050505050565b612459886020015160018151811061244c5761244c613b24565b602002602001015161285a565b9a509750612552945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f52656365697665642061206e6f6465207769746820616e20756e6b6e6f776e2060448201527f70726566697800000000000000000000000000000000000000000000000000006064820152608401610550565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f526563656976656420616e20756e706172736561626c65206e6f64652e0000006044820152606401610550565b8061255c81613a94565b9150506120c5565b507f800000000000000000000000000000000000000000000000000000000000000084148661259387866128b4565b909e909d50909b509950505050505050505050565b602081015180516060916114b1916125c290600190613693565b8151811061202657612026613b24565b6040805180820182526000808252602091820152815180830190925282518252808301908201526060906114b190612996565b6060600080600061261585612bc9565b91945092509050600081600181111561263057612630613b98565b14612697576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c502062797465732076616c75652e00000000000000006044820152606401610550565b6126a685602001518484612fd0565b95945050505050565b60606000825160026126c191906138e5565b67ffffffffffffffff8111156126d9576126d96132fa565b6040519080825280601f01601f191660200182016040528015612703576020820181803683370190505b50905060005b835181101561282b57600484828151811061272657612726613b24565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c8261275b8360026138e5565b8151811061276b5761276b613b24565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060108482815181106127ae576127ae613b24565b01602001516127c0919060f81c613b53565b60f81b826127cf8360026138e5565b6127da906001613a16565b815181106127ea576127ea613b24565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061282381613a94565b915050612709565b5092915050565b600060208251101561284657506020015190565b818060200190518101906114b191906139e9565b6000606060208360000151101561287b57612874836130af565b9050612887565b61288483612605565b90505b61181d81612832565b60606114b16128af836020015160008151811061202657612026613b24565b6126af565b6060825182106128d357506040805160208101909152600081526114b1565b6114ae83838486516128e59190613693565b6130ba565b6000805b8084511180156128fe5750808351115b801561297f575082818151811061291757612917613b24565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191684828151811061295657612956613b24565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156114ae578061298e81613a94565b9150506128ee565b60606000806129a484612bc9565b919350909150600190508160018111156129c0576129c0613b98565b14612a27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c50206c6973742076616c75652e0000000000000000006044820152606401610550565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612a405790505090506000835b8651811015612bbe5760208210612b06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50726f766964656420524c50206c6973742065786365656473206d6178206c6960448201527f7374206c656e6774682e000000000000000000000000000000000000000000006064820152608401610550565b600080612b436040518060400160405280858c60000151612b279190613693565b8152602001858c60200151612b3c9190613a16565b9052612bc9565b509150915060405180604001604052808383612b5f9190613a16565b8152602001848b60200151612b749190613a16565b815250858581518110612b8957612b89613b24565b6020908102919091010152612b9f600185613a16565b9350612bab8183613a16565b612bb59084613a16565b92505050612a6d565b508152949350505050565b600080600080846000015111612c3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f524c50206974656d2063616e6e6f74206265206e756c6c2e00000000000000006044820152606401610550565b6020840151805160001a607f8111612c60576000600160009450945094505050612fc9565b60b78111612cf6576000612c75608083613693565b905080876000015111612ce4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e76616c696420524c502073686f727420737472696e672e000000000000006044820152606401610550565b60019550935060009250612fc9915050565b60bf8111612e19576000612d0b60b783613693565b905080876000015111612d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f496e76616c696420524c50206c6f6e6720737472696e67206c656e6774682e006044820152606401610550565b600183015160208290036101000a9004612d948183613a16565b885111612dfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c50206c6f6e6720737472696e672e00000000000000006044820152606401610550565b612e08826001613a16565b9650945060009350612fc992505050565b60f78111612eae576000612e2e60c083613693565b905080876000015111612e9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c502073686f7274206c6973742e0000000000000000006044820152606401610550565b600195509350849250612fc9915050565b6000612ebb60f783613693565b905080876000015111612f2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c696420524c50206c6f6e67206c697374206c656e6774682e0000006044820152606401610550565b600183015160208290036101000a9004612f448183613a16565b885111612fad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420524c50206c6f6e67206c6973742e000000000000000000006044820152606401610550565b612fb8826001613a16565b9650945060019350612fc992505050565b9193909250565b606060008267ffffffffffffffff811115612fed57612fed6132fa565b6040519080825280601f01601f191660200182016040528015613017576020820181803683370190505b50905080516000141561302b57905061181d565b60006130378587613a16565b90506020820160005b61304b602087613986565b8110156130825782518252613061602084613a16565b925061306e602083613a16565b91508061307a81613a94565b915050613040565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b60606114b1826132a7565b6060816130c881601f613a16565b1015613130576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b8261313b8382613a16565b10156131a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b6131ad8284613a16565b84511015613217576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610550565b606082158015613236576040519150600082526020820160405261329e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561326f578051835260209283019201613257565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b60606114b1826020015160008460000151612fd0565b6000602082840312156132cf57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146116bb57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613370576133706132fa565b604052919050565b600080600080600060a0868803121561339057600080fd5b613399866132d6565b94506020808701359450604087013567ffffffffffffffff80821682146133bf57600080fd5b90945060608801359081151582146133d657600080fd5b909350608088013590808211156133ec57600080fd5b818901915089601f83011261340057600080fd5b813581811115613412576134126132fa565b613442847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613329565b91508082528a8482850101111561345857600080fd5b80848401858401376000848284010152508093505050509295509295909350565b60008083601f84011261348b57600080fd5b50813567ffffffffffffffff8111156134a357600080fd5b6020830191508360208285010111156134bb57600080fd5b9250929050565b60008060008060008060008060008060006101808c8e0312156134e457600080fd5b8b359a506134f460208d016132d6565b995061350260408d016132d6565b985060608c0135975060808c0135965067ffffffffffffffff60a08d0135111561352b57600080fd5b61353b8d60a08e01358e01613479565b909650945060c08c0135935060808c8e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2001121561357957600080fd5b60e08c01925067ffffffffffffffff6101608d0135111561359957600080fd5b6135aa8d6101608e01358e01613479565b81935080925050509295989b509295989b9093969950565b6000815180845260005b818110156135e8576020818501810151868301820152016135cc565b818111156135fa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b85815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611e9060a08301846135c2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156136a5576136a5613664565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826136e8576136e86136aa565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561373c5761373c613664565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561377b5761377b613664565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0183138116156137af576137af613664565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000841360008413858304851182821616156137f6576137f6613664565b7f8000000000000000000000000000000000000000000000000000000000000000600087128682058812818416161561383157613831613664565b6000871292508782058712848416161561384d5761384d613664565b8785058712818416161561386357613863613664565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038413811516156138ab576138ab613664565b827f80000000000000000000000000000000000000000000000000000000000000000384128116156138df576138df613664565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561391d5761391d613664565b500290565b600067ffffffffffffffff80831681851680830382111561394557613945613664565b01949350505050565b60006fffffffffffffffffffffffffffffffff8083168185168183048111821515161561397d5761397d613664565b02949350505050565b600082613995576139956136aa565b500490565b6000604082840312156139ac57600080fd5b6040516040810181811067ffffffffffffffff821117156139cf576139cf6132fa565b604052825181526020928301519281019290925250919050565b6000602082840312156139fb57600080fd5b5051919050565b600082613a1157613a116136aa565b500690565b60008219821115613a2957613a29613664565b500190565b600060808284031215613a4057600080fd5b6040516080810181811067ffffffffffffffff82111715613a6357613a636132fa565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613ac657613ac6613664565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613b1860c08301846135c2565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680613b6657613b666136aa565b8060ff84160691505092915050565b600060ff821660ff841680821015613b8f57613b8f613664565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080a000a"
var OptimismPortalDeployedBin = "0x60806040526004361061012c5760003560e01c8063a14238e7116100a5578063cff0ab9611610074578063eecf1c3611610059578063eecf1c3614610427578063f4daa2911461043a578063f786becd1461046e57600080fd5b8063cff0ab9614610373578063e9e05c421461041457600080fd5b8063a14238e7146102e5578063c8b9153114610315578063ca3e99ba14610349578063cd7c97891461035e57600080fd5b80636bf2606a116100fc5780638129fc1c116100e15780638129fc1c1461028d578063867ead13146102a25780639bf62d82146102b857600080fd5b80636bf2606a146102295780636dbffb781461025d57600080fd5b80621c2ff61461015857806313620abd146101b657806364b79208146101ef5780636bb0291e1461021457600080fd5b36610153576101513334620186a06000604051806020016040528060008152506104a2565b005b600080fd5b34801561016457600080fd5b5061018c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c257600080fd5b506101ce633b9aca0081565b6040516fffffffffffffffffffffffffffffffff90911681526020016101ad565b3480156101fb57600080fd5b50610206627a120081565b6040519081526020016101ad565b34801561022057600080fd5b50610206600481565b34801561023557600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561026957600080fd5b5061027d610278366004613359565b610948565b60405190151581526020016101ad565b34801561029957600080fd5b50610151610c56565b3480156102ae57600080fd5b5061020661271081565b3480156102c457600080fd5b5060335461018c9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102f157600080fd5b5061027d610300366004613359565b60346020526000908152604090205460ff1681565b34801561032157600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561035557600080fd5b50610206610d31565b34801561036a57600080fd5b50610206600881565b34801561037f57600080fd5b506001546103db906fffffffffffffffffffffffffffffffff81169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b604080516fffffffffffffffffffffffffffffffff909416845267ffffffffffffffff92831660208501529116908201526060016101ad565b610151610422366004613414565b6104a2565b61015161043536600461355e565b610d42565b34801561044657600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b34801561047a57600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b8260005a905083156105595773ffffffffffffffffffffffffffffffffffffffff87161561055957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f4f7074696d69736d506f7274616c3a206d7573742073656e6420746f2061646460448201527f72657373283029207768656e206372656174696e67206120636f6e747261637460648201526084015b60405180910390fd5b3332811461057a575033731111000000000000000000000000000000001111015b8773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f78231ae6eb73366f912bb1d64351601fb76344c537bbab635ce14d0f376f0195348a8a8a8a6040516105df9594939291906136c9565b60405180910390a35060015460009061061e907801000000000000000000000000000000000000000000000000900467ffffffffffffffff164361372f565b905080156107a75760006106366004627a1200613775565b6001546106619190700100000000000000000000000000000000900467ffffffffffffffff166137dd565b9050600060086106756004627a1200613775565b6001546106959085906fffffffffffffffffffffffffffffffff16613851565b61069f9190613775565b6106a99190613775565b6001549091506000906106f5906106df906106d79085906fffffffffffffffffffffffffffffffff1661390d565b612710611455565b6fffffffffffffffffffffffffffffffff611470565b90506001841115610768576107656106df670de0b6b3a764000061075161071d600883613775565b61072f90670de0b6b3a76400006137dd565b61073a60018a61372f565b61074c90670de0b6b3a7640000613981565b61147f565b61075b9085613851565b6106d79190613775565b90505b6fffffffffffffffffffffffffffffffff16780100000000000000000000000000000000000000000000000067ffffffffffffffff4316021760015550505b600180548491906010906107da908490700100000000000000000000000000000000900467ffffffffffffffff166139be565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550627a1200600160000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1613156108b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f4f7074696d69736d506f7274616c3a2063616e6e6f7420627579206d6f72652060448201527f676173207468616e20617661696c61626c6520676173206c696d6974000000006064820152608401610550565b6001546000906108e2906fffffffffffffffffffffffffffffffff1667ffffffffffffffff86166139ea565b6fffffffffffffffffffffffffffffffff169050600061090648633b9aca006114b0565b6109109083613a22565b905060005a61091f908661372f565b90508082111561093b5761093b610936828461372f565b6114c0565b5050505050505050505050565b6040517fa25ae55700000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a25ae557906024016040805180830381865afa1580156109d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fb9190613a36565b8051909150610c1d5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663529933df6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a959190613a85565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634ab65d736040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b04573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b289190613a85565b905084811115610b3d57506000949350505050565b600082610b4a838861372f565b610b549190613a9e565b905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663a25ae557610b9c838661372f565b610ba69089613ab2565b6040518263ffffffff1660e01b8152600401610bc491815260200190565b6040805180830381865afa158015610be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c049190613a36565b8051909450610c195750600095945050505050565b5050505b7f00000000000000000000000000000000000000000000000000000000000000008160200151610c4d9190613ab2565b42119392505050565b6000610c6260016114ee565b90508015610c9757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead179055610ccb611679565b8015610d2e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b610d3f6004627a1200613775565b81565b60335473ffffffffffffffffffffffffffffffffffffffff1661dead14610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a2063616e206f6e6c79207472696767657260448201527f206f6e65207769746864726177616c20706572207472616e73616374696f6e006064820152608401610550565b73ffffffffffffffffffffffffffffffffffffffff8916301415610e91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f4f7074696d69736d506f7274616c3a20796f752063616e6e6f742073656e642060448201527f6d6573736167657320746f2074686520706f7274616c20636f6e7472616374006064820152608401610550565b6040517fa25ae557000000000000000000000000000000000000000000000000000000008152600481018590526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063a25ae557906024016040805180830381865afa158015610f1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f429190613a36565b90507f00000000000000000000000000000000000000000000000000000000000000008160200151610f749190613ab2565b4211611002576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f4f7074696d69736d506f7274616c3a2070726f706f73616c206973206e6f742060448201527f7965742066696e616c697a6564000000000000000000000000000000000000006064820152608401610550565b61101961101436869003860186613aca565b61175c565b8151146110a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f7074696d69736d506f7274616c3a20696e76616c6964206f7574707574207260448201527f6f6f742070726f6f6600000000000000000000000000000000000000000000006064820152608401610550565b60006110ee8d8d8d8d8d8d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117b892505050565b905061113581866040013586868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506117f792505050565b6111c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4f7074696d69736d506f7274616c3a20696e76616c696420776974686472617760448201527f616c20696e636c7573696f6e2070726f6f6600000000000000000000000000006064820152608401610550565b60008181526034602052604090205460ff1615611260576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4f7074696d69736d506f7274616c3a207769746864726177616c20686173206160448201527f6c7265616479206265656e2066696e616c697a656400000000000000000000006064820152608401610550565b600081815260346020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556112a3614e208a613ab2565b5a1015611332576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4f7074696d69736d506f7274616c3a20696e73756666696369656e742067617360448201527f20746f2066696e616c697a65207769746864726177616c0000000000000000006064820152608401610550565b603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8e16179055604080516020601f8a018190048102820181019092528881526000916113bb918e918d918f918691908f908f90819084018382808284376000920191909152506118c092505050565b50603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead17905560405190915082907fdb5c7652857aa163daadd670e116628fb42e869d8ac4251ef8971d9e5727df1b9061142190841515815260200190565b60405180910390a25050505050505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6000818312156114655781611467565b825b90505b92915050565b60008183126114655781611467565b6000611467670de0b6b3a7640000836114978661194b565b6114a19190613851565b6114ab9190613775565b611b8f565b6000818310156114655781611467565b6000805a90505b825a6114d3908361372f565b10156114e9576114e282613b30565b91506114c7565b505050565b60008054610100900460ff16156115a5578160ff1660011480156115115750303b155b61159d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b506000919050565b60005460ff80841691161061163c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610550565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff16611710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610550565b60408051606081018252633b9aca00808252600060208301524367ffffffffffffffff169190920181905278010000000000000000000000000000000000000000000000000217600155565b6000816000015182602001518360400151846060015160405160200161179b949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b60008686868686866040516020016117d596959493929190613b69565b6040516020818303038152906040528051906020012090509695505050505050565b604080516020810185905260009181018290528190606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830181905292506118b59101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828201909152600182527f01000000000000000000000000000000000000000000000000000000000000006020830152908587611dce565b9150505b9392505050565b6000606060008060008661ffff1667ffffffffffffffff8111156118e6576118e6613396565b6040519080825280601f01601f191660200182016040528015611910576020820181803683370190505b5090506000808751602089018b8e8ef191503d925086831115611931578692505b828152826000602083013e90999098509650505050505050565b60008082136119b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b600060606119c384611df2565b03609f8181039490941b90931c6c465772b2bbbb5f824b15207a3081018102606090811d6d0388eaa27412d5aca026815d636e018202811d6d0df99ac502031bf953eff472fdcc018202811d6d13cdffb29d51d99322bdff5f2211018202811d6d0a0f742023def783a307a986912e018202811d6d01920d8043ca89b5239253284e42018202811d6c0b7a86d7375468fac667a0a527016c29508e458543d8aa4df2abee7883018302821d6d0139601a2efabe717e604cbb4894018302821d6d02247f7a7b6594320649aa03aba1018302821d7fffffffffffffffffffffffffffffffffffffff73c0c716a594e00d54e3c4cbc9018302821d7ffffffffffffffffffffffffffffffffffffffdc7b88c420e53a9890533129f6f01830290911d7fffffffffffffffffffffffffffffffffffffff465fda27eb4d63ded474e5f832019091027ffffffffffffffff5f6af8f7b3396644f18e157960000000000000000000000000105711340daa0d5f769dba1915cef59f0815a5506027d0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b393909302929092017d57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b88642840160ae1d92915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c18213611bc057506000919050565b680755bf798b4a1bf1e58212611c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4558505f4f564552464c4f5700000000000000000000000000000000000000006044820152606401610550565b6503782dace9d9604e83901b059150600060606bb17217f7d1cf79abc9e3b39884821b056b80000000000000000000000001901d6bb17217f7d1cf79abc9e3b39881029093037fffffffffffffffffffffffffffffffffffffffdbf3ccf1604d263450f02a550481018102606090811d6d0277594991cfc85f6e2461837cd9018202811d7fffffffffffffffffffffffffffffffffffffe5adedaa1cb095af9e4da10e363c018202811d6db1bbb201f443cf962f1a1d3db4a5018202811d7ffffffffffffffffffffffffffffffffffffd38dc772608b0ae56cce01296c0eb018202811d6e05180bb14799ab47a8a8cb2a527d57016d02d16720577bd19bf614176fe9ea6c10fe68e7fd37d0007b713f765084018402831d9081019084017ffffffffffffffffffffffffffffffffffffffe2c69812cf03b0763fd454a8f7e010290911d6e0587f503bb6ea29d25fcb7401964500190910279d835ebba824c98fb31b83b2ca45c000000000000000000000000010574029d9dc38563c32e5c2f6dc192ee70ef65f9978af30260c3939093039290921c92915050565b600080611dda86611ec8565b9050611de881868686611efa565b9695505050505050565b6000808211611e5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f554e444546494e454400000000000000000000000000000000000000000000006044820152606401610550565b5060016fffffffffffffffffffffffffffffffff821160071b82811c67ffffffffffffffff1060061b1782811c63ffffffff1060051b1782811c61ffff1060041b1782811c60ff10600390811b90911783811c600f1060021b1783811c909110821b1791821c111790565b60608180519060200120604051602001611ee491815260200190565b6040516020818303038152906040529050919050565b6000806000611f0a878686611f37565b91509150818015611f2c57508051602080830191909120875191880191909120145b979650505050505050565b600060606000611f468561202c565b90506000806000611f58848a89612127565b81519295509093509150158080611f6c5750815b611fd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f50726f76696465642070726f6f6620697320696e76616c69642e0000000000006044820152606401610550565b600081611fee576040518060200160405280600081525061201a565b61201a86611ffd60018861372f565b8151811061200d5761200d613bc0565b6020026020010151612644565b919b919a509098505050505050505050565b606060006120398361266e565b90506000815167ffffffffffffffff81111561205757612057613396565b60405190808252806020026020018201604052801561209c57816020015b60408051808201909152606080825260208201528152602001906001900390816120755790505b50905060005b825181101561211f5760006120cf8483815181106120c2576120c2613bc0565b60200260200101516126a1565b905060405180604001604052808281526020016120eb8361266e565b81525083838151811061210057612100613bc0565b602002602001018190525050808061211790613b30565b9150506120a2565b509392505050565b600060608180806121378761274b565b9050600086905060008061215e604051806040016040528060608152602001606081525090565b60005b8c51811015612600578c818151811061217c5761217c613bc0565b6020026020010151915082846121929190613ab2565b935061219f600188613ab2565b96508361221d57815180516020909101208514612218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c696420726f6f7420686173680000000000000000000000000000006044820152606401610550565b61230e565b81515160201161229957815180516020909101208514612218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206c6172676520696e7465726e616c206861736800000000006044820152606401610550565b846122a783600001516128ce565b1461230e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c696420696e7465726e616c206e6f646520686173680000000000006044820152606401610550565b61231a60106001613ab2565b826020015151141561239357855184141561233457612600565b600086858151811061234857612348613bc0565b602001015160f81c60f81b60f81c9050600083602001518260ff168151811061237357612373613bc0565b60200260200101519050612386816128f6565b96506001945050506125ee565b6002826020015151141561258c5760006123ac8361292c565b90506000816000815181106123c3576123c3613bc0565b016020015160f81c905060006123da600283613bef565b6123e5906002613c11565b905060006123f6848360ff16612950565b905060006124048b8a612950565b905060006124128383612986565b905060ff851660021480612429575060ff85166003145b1561247f5780835114801561243e5750808251145b156124505761244d818b613ab2565b99505b507f80000000000000000000000000000000000000000000000000000000000000009950612600945050505050565b60ff85161580612492575060ff85166001145b1561250457825181146124ce57507f80000000000000000000000000000000000000000000000000000000000000009950612600945050505050565b6124f588602001516001815181106124e8576124e8613bc0565b60200260200101516128f6565b9a5097506125ee945050505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f52656365697665642061206e6f6465207769746820616e20756e6b6e6f776e2060448201527f70726566697800000000000000000000000000000000000000000000000000006064820152608401610550565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f526563656976656420616e20756e706172736561626c65206e6f64652e0000006044820152606401610550565b806125f881613b30565b915050612161565b507f800000000000000000000000000000000000000000000000000000000000000084148661262f8786612950565b909e909d50909b509950505050505050505050565b6020810151805160609161146a9161265e9060019061372f565b815181106120c2576120c2613bc0565b60408051808201825260008082526020918201528151808301909252825182528083019082015260609061146a90612a32565b606060008060006126b185612c65565b9194509250905060008160018111156126cc576126cc613c34565b14612733576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c502062797465732076616c75652e00000000000000006044820152606401610550565b6127428560200151848461306c565b95945050505050565b606060008251600261275d9190613981565b67ffffffffffffffff81111561277557612775613396565b6040519080825280601f01601f19166020018201604052801561279f576020820181803683370190505b50905060005b83518110156128c75760048482815181106127c2576127c2613bc0565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c826127f7836002613981565b8151811061280757612807613bc0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350601084828151811061284a5761284a613bc0565b016020015161285c919060f81c613bef565b60f81b8261286b836002613981565b612876906001613ab2565b8151811061288657612886613bc0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350806128bf81613b30565b9150506127a5565b5092915050565b60006020825110156128e257506020015190565b8180602001905181019061146a9190613a85565b60006060602083600001511015612917576129108361314b565b9050612923565b612920836126a1565b90505b6118b9816128ce565b606061146a61294b83602001516000815181106120c2576120c2613bc0565b61274b565b60608251821061296f575060408051602081019091526000815261146a565b6114678383848651612981919061372f565b613156565b6000805b80845111801561299a5750808351115b8015612a1b57508281815181106129b3576129b3613bc0565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168482815181106129f2576129f2613bc0565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016145b156114675780612a2a81613b30565b91505061298a565b6060600080612a4084612c65565b91935090915060019050816001811115612a5c57612a5c613c34565b14612ac3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c50206c6973742076616c75652e0000000000000000006044820152606401610550565b6040805160208082526104208201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081612adc5790505090506000835b8651811015612c5a5760208210612ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f50726f766964656420524c50206c6973742065786365656473206d6178206c6960448201527f7374206c656e6774682e000000000000000000000000000000000000000000006064820152608401610550565b600080612bdf6040518060400160405280858c60000151612bc3919061372f565b8152602001858c60200151612bd89190613ab2565b9052612c65565b509150915060405180604001604052808383612bfb9190613ab2565b8152602001848b60200151612c109190613ab2565b815250858581518110612c2557612c25613bc0565b6020908102919091010152612c3b600185613ab2565b9350612c478183613ab2565b612c519084613ab2565b92505050612b09565b508152949350505050565b600080600080846000015111612cd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f524c50206974656d2063616e6e6f74206265206e756c6c2e00000000000000006044820152606401610550565b6020840151805160001a607f8111612cfc576000600160009450945094505050613065565b60b78111612d92576000612d1160808361372f565b905080876000015111612d80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e76616c696420524c502073686f727420737472696e672e000000000000006044820152606401610550565b60019550935060009250613065915050565b60bf8111612eb5576000612da760b78361372f565b905080876000015111612e16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f496e76616c696420524c50206c6f6e6720737472696e67206c656e6774682e006044820152606401610550565b600183015160208290036101000a9004612e308183613ab2565b885111612e99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f496e76616c696420524c50206c6f6e6720737472696e672e00000000000000006044820152606401610550565b612ea4826001613ab2565b965094506000935061306592505050565b60f78111612f4a576000612eca60c08361372f565b905080876000015111612f39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c696420524c502073686f7274206c6973742e0000000000000000006044820152606401610550565b600195509350849250613065915050565b6000612f5760f78361372f565b905080876000015111612fc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c696420524c50206c6f6e67206c697374206c656e6774682e0000006044820152606401610550565b600183015160208290036101000a9004612fe08183613ab2565b885111613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c696420524c50206c6f6e67206c6973742e000000000000000000006044820152606401610550565b613054826001613ab2565b965094506001935061306592505050565b9193909250565b606060008267ffffffffffffffff81111561308957613089613396565b6040519080825280601f01601f1916602001820160405280156130b3576020820181803683370190505b5090508051600014156130c75790506118b9565b60006130d38587613ab2565b90506020820160005b6130e7602087613a22565b81101561311e57825182526130fd602084613ab2565b925061310a602083613ab2565b91508061311681613b30565b9150506130dc565b5060006001602087066020036101000a039050808251168119845116178252839450505050509392505050565b606061146a82613343565b60608161316481601f613ab2565b10156131cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b826131d78382613ab2565b101561323f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f770000000000000000000000000000000000006044820152606401610550565b6132498284613ab2565b845110156132b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e64730000000000000000000000000000006044820152606401610550565b6060821580156132d2576040519150600082526020820160405261333a565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561330b5780518352602092830192016132f3565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b606061146a82602001516000846000015161306c565b60006020828403121561336b57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461167457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561340c5761340c613396565b604052919050565b600080600080600060a0868803121561342c57600080fd5b61343586613372565b94506020808701359450604087013567ffffffffffffffff808216821461345b57600080fd5b909450606088013590811515821461347257600080fd5b9093506080880135908082111561348857600080fd5b818901915089601f83011261349c57600080fd5b8135818111156134ae576134ae613396565b6134de847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016133c5565b91508082528a848285010111156134f457600080fd5b80848401858401376000848284010152508093505050509295509295909350565b60008083601f84011261352757600080fd5b50813567ffffffffffffffff81111561353f57600080fd5b60208301915083602082850101111561355757600080fd5b9250929050565b60008060008060008060008060008060006101808c8e03121561358057600080fd5b8b359a5061359060208d01613372565b995061359e60408d01613372565b985060608c0135975060808c0135965067ffffffffffffffff60a08d013511156135c757600080fd5b6135d78d60a08e01358e01613515565b909650945060c08c0135935060808c8e037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2001121561361557600080fd5b60e08c01925067ffffffffffffffff6101608d0135111561363557600080fd5b6136468d6101608e01358e01613515565b81935080925050509295989b509295989b9093969950565b6000815180845260005b8181101561368457602081850181015186830182015201613668565b81811115613696576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b85815284602082015267ffffffffffffffff84166040820152821515606082015260a060808201526000611f2c60a083018461365e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561374157613741613700565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261378457613784613746565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156137d8576137d8613700565b500590565b6000808312837f80000000000000000000000000000000000000000000000000000000000000000183128115161561381757613817613700565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561384b5761384b613700565b50500390565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008413600084138583048511828216161561389257613892613700565b7f800000000000000000000000000000000000000000000000000000000000000060008712868205881281841616156138cd576138cd613700565b600087129250878205871284841616156138e9576138e9613700565b878505871281841616156138ff576138ff613700565b505050929093029392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0384138115161561394757613947613700565b827f800000000000000000000000000000000000000000000000000000000000000003841281161561397b5761397b613700565b50500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156139b9576139b9613700565b500290565b600067ffffffffffffffff8083168185168083038211156139e1576139e1613700565b01949350505050565b60006fffffffffffffffffffffffffffffffff80831681851681830481118215151615613a1957613a19613700565b02949350505050565b600082613a3157613a31613746565b500490565b600060408284031215613a4857600080fd5b6040516040810181811067ffffffffffffffff82111715613a6b57613a6b613396565b604052825181526020928301519281019290925250919050565b600060208284031215613a9757600080fd5b5051919050565b600082613aad57613aad613746565b500690565b60008219821115613ac557613ac5613700565b500190565b600060808284031215613adc57600080fd5b6040516080810181811067ffffffffffffffff82111715613aff57613aff613396565b8060405250823581526020830135602082015260408301356040820152606083013560608201528091505092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613b6257613b62613700565b5060010190565b868152600073ffffffffffffffffffffffffffffffffffffffff808816602084015280871660408401525084606083015283608083015260c060a0830152613bb460c083018461365e565b98975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff831680613c0257613c02613746565b8060ff84160691505092915050565b600060ff821660ff841680821015613c2b57613c2b613700565b90039392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c634300080a000a"
......@@ -3,10 +3,10 @@ module github.com/ethereum-optimism/optimism/op-e2e
go 1.18
require (
github.com/ethereum-optimism/optimism/op-batcher v0.0.0
github.com/ethereum-optimism/optimism/op-bindings v0.0.0
github.com/ethereum-optimism/optimism/op-node v0.0.0
github.com/ethereum-optimism/optimism/op-proposer v0.0.0
github.com/ethereum-optimism/optimism/op-batcher v0.3.0
github.com/ethereum-optimism/optimism/op-bindings v0.3.0
github.com/ethereum-optimism/optimism/op-node v0.3.0
github.com/ethereum-optimism/optimism/op-proposer v0.3.0
github.com/ethereum/go-ethereum v1.10.17
github.com/libp2p/go-libp2p v0.18.1
github.com/libp2p/go-libp2p-core v0.15.0
......@@ -160,11 +160,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace (
github.com/ethereum-optimism/optimism/op-batcher v0.0.0 => ../op-batcher
github.com/ethereum-optimism/optimism/op-bindings v0.0.0 => ../op-bindings
github.com/ethereum-optimism/optimism/op-node v0.0.0 => ../op-node
github.com/ethereum-optimism/optimism/op-proposer v0.0.0 => ../op-proposer
)
replace github.com/ethereum/go-ethereum v1.10.17 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d
......@@ -249,7 +249,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/optimism/op-batcher v0.3.0 h1:rNEUyu7ZTUZc1W1lM9lO71w/HZ9pjQtnNwR/e1I0XyQ=
github.com/ethereum-optimism/optimism/op-batcher v0.3.0/go.mod h1:1imFCpIIA70WVZX7gp4dH/ZSnfqcG/WNvVp8Xm2s2VU=
github.com/ethereum-optimism/optimism/op-bindings v0.0.0-20220614233543-0d8fa52afca2/go.mod h1:e9mMYiVsdJf9BI//FdaA77BwNNgNMR043JtB7CPXNxY=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0 h1:d2Mwb8FzR2zuhW0sS5xFKWz/6VFPTEIE+XINqZj0Rv4=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0/go.mod h1:CrvUVIISKcyJ7o27ub/HY4Kq9wEJQxrGmWthTqxPSGo=
github.com/ethereum-optimism/optimism/op-node v0.3.0 h1:jep/cbIbP7fjBSAR48yk5NJVEoGYvoNlYI00KpBI6Mw=
github.com/ethereum-optimism/optimism/op-node v0.3.0/go.mod h1:iF9AhYjr8jNeoCDNP/Vs/ywQ2USZU5L66AxZbSAUi0E=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0 h1:K1ipZt3TLD0BJi7tKOmx8tCLXj9i4f4baBIhbPmUxk4=
github.com/ethereum-optimism/optimism/op-proposer v0.3.0/go.mod h1:GcQ9VCWz2zEVexecq5IYo/2eadK/y7IBOEfx4YV1QJk=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d h1:AYFFbxrz7kLyFbvNHGhUPZQT8KnN1PPjCj4oAcgaVCk=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d/go.mod h1:8AfU1epKggKxDt9wr7rH5KmCeiT3yT0sEvroru1mO6Q=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
......
......@@ -2,15 +2,12 @@ FROM golang:1.18.0-alpine3.15 as builder
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
COPY ./op-node/go.mod /app/op-node/go.mod
COPY ./op-node/go.sum /app/op-node/go.sum
# build op-node with local monorepo go modules
COPY ./op-node/docker.go.work /app/go.work
COPY ./op-bindings /app/op-bindings
COPY ./op-node /app/op-node
WORKDIR /app/op-node
RUN go mod download -x
COPY ./op-node /app/op-node
RUN make op-node
......
go 1.18
use (
./op-bindings
./op-node
)
......@@ -3,7 +3,7 @@ module github.com/ethereum-optimism/optimism/op-node
go 1.18
require (
github.com/ethereum-optimism/optimism/op-bindings v0.0.0
github.com/ethereum-optimism/optimism/op-bindings v0.3.0
github.com/ethereum/go-ethereum v1.10.17
github.com/golang/snappy v0.0.4
github.com/google/go-cmp v0.5.8
......@@ -173,8 +173,6 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum-optimism/optimism/op-bindings v0.0.0 => ../op-bindings
replace github.com/ethereum/go-ethereum v1.10.17 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d
// For local debugging:
......
......@@ -232,6 +232,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/optimism/op-bindings v0.0.0-20220614233543-0d8fa52afca2/go.mod h1:e9mMYiVsdJf9BI//FdaA77BwNNgNMR043JtB7CPXNxY=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0 h1:d2Mwb8FzR2zuhW0sS5xFKWz/6VFPTEIE+XINqZj0Rv4=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0/go.mod h1:CrvUVIISKcyJ7o27ub/HY4Kq9wEJQxrGmWthTqxPSGo=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d h1:AYFFbxrz7kLyFbvNHGhUPZQT8KnN1PPjCj4oAcgaVCk=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d/go.mod h1:8AfU1epKggKxDt9wr7rH5KmCeiT3yT0sEvroru1mO6Q=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
......
package derive
import (
"context"
"fmt"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
)
// L1ReceiptsFetcher fetches L1 header info and receipts for the payload attributes derivation (the info tx and deposits)
type L1ReceiptsFetcher interface {
InfoByHash(ctx context.Context, hash common.Hash) (eth.L1Info, error)
Fetch(ctx context.Context, blockHash common.Hash) (eth.L1Info, types.Transactions, types.Receipts, error)
}
// PreparePayloadAttributes prepares a PayloadAttributes template that is ready to build a L2 block with deposits only, on top of the given l2Parent, with the given epoch as L1 origin.
// The template defaults to NoTxPool=true, and no sequencer transactions: the caller has to modify the template to add transactions,
// by setting NoTxPool=false as sequencer, or by appending batch transactions as verifier.
// The severity of the error is returned; a crit=false error means there was a temporary issue, like a failed RPC or time-out.
// A crit=true error means the input arguments are inconsistent or invalid.
func PreparePayloadAttributes(ctx context.Context, cfg *rollup.Config, dl L1ReceiptsFetcher, l2Parent eth.L2BlockRef, epoch eth.BlockID) (attrs *eth.PayloadAttributes, crit bool, err error) {
var l1Info eth.L1Info
var depositTxs []hexutil.Bytes
var seqNumber uint64
// If the L1 origin changed this block, then we are in the first block of the epoch. In this
// case we need to fetch all transaction receipts from the L1 origin block so we can scan for
// user deposits.
if l2Parent.L1Origin.Number != epoch.Number {
info, _, receipts, err := dl.Fetch(ctx, epoch.Hash)
if err != nil {
return nil, false, fmt.Errorf("failed to fetch L1 block info and receipts: %w", err)
}
if l2Parent.L1Origin.Hash != info.ParentHash() {
return nil, true, fmt.Errorf("cannot create new block with L1 origin %s (parent %s) on top of L1 origin %s", epoch, info.ParentHash(), l2Parent.L1Origin)
}
deposits, err := DeriveDeposits(receipts, cfg.DepositContractAddress)
if err != nil {
return nil, true, fmt.Errorf("failed to derive some deposits: %w", err)
}
l1Info = info
depositTxs = deposits
seqNumber = 0
} else {
if l2Parent.L1Origin.Hash != epoch.Hash {
return nil, true, fmt.Errorf("cannot create new block with L1 origin %s in conflict with L1 origin %s", epoch, l2Parent.L1Origin)
}
info, err := dl.InfoByHash(ctx, epoch.Hash)
if err != nil {
return nil, false, fmt.Errorf("failed to fetch L1 block info: %w", err)
}
l1Info = info
depositTxs = nil
seqNumber = l2Parent.SequenceNumber + 1
}
l1InfoTx, err := L1InfoDepositBytes(seqNumber, l1Info)
if err != nil {
return nil, true, fmt.Errorf("failed to create l1InfoTx: %w", err)
}
txs := make([]hexutil.Bytes, 0, 1+len(depositTxs))
txs = append(txs, l1InfoTx)
txs = append(txs, depositTxs...)
return &eth.PayloadAttributes{
Timestamp: hexutil.Uint64(l2Parent.Time + cfg.BlockTime),
PrevRandao: eth.Bytes32(l1Info.MixDigest()),
SuggestedFeeRecipient: cfg.FeeRecipientAddress,
Transactions: txs,
NoTxPool: true,
}, false, nil
}
......@@ -8,16 +8,9 @@ import (
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
type L1ReceiptsFetcher interface {
Fetch(ctx context.Context, blockHash common.Hash) (eth.L1Info, types.Transactions, types.Receipts, error)
}
type AttributesQueueOutput interface {
AddSafeAttributes(attributes *eth.PayloadAttributes)
SafeL2Head() eth.L2BlockRef
......@@ -55,82 +48,43 @@ func (aq *AttributesQueue) Step(ctx context.Context, outer Progress) error {
if changed, err := aq.progress.Update(outer); err != nil || changed {
return err
}
attr, err := aq.DeriveL2Inputs(ctx, aq.next.SafeL2Head())
if err != nil {
return err
}
aq.next.AddSafeAttributes(attr)
return nil
}
func (aq *AttributesQueue) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
aq.batches = aq.batches[:0]
aq.progress = aq.next.Progress()
return io.EOF
}
func (aq *AttributesQueue) SafeL2Head() eth.L2BlockRef {
return aq.next.SafeL2Head()
}
// DeriveL2Inputs turns the next L2 batch into an Payload Attributes that builds off of the safe head
func (aq *AttributesQueue) DeriveL2Inputs(ctx context.Context, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) {
if len(aq.batches) == 0 {
return nil, io.EOF
return io.EOF
}
batch := aq.batches[0]
seqNumber := l2SafeHead.SequenceNumber + 1
// Check if we need to advance an epoch & update local state
if l2SafeHead.L1Origin != batch.Epoch() {
aq.log.Info("advancing epoch in the attributes queue", "l2SafeHead", l2SafeHead, "l2SafeHead_origin", l2SafeHead.L1Origin, "batch_timestamp", batch.Timestamp, "batch_epoch", batch.Epoch())
seqNumber = 0
}
fetchCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
l1Info, _, receipts, err := aq.dl.Fetch(fetchCtx, batch.EpochHash)
attrs, crit, err := PreparePayloadAttributes(fetchCtx, aq.config, aq.dl, aq.next.SafeL2Head(), batch.Epoch())
if err != nil {
aq.log.Error("failed to fetch L1 block info", "l1Origin", batch.Epoch(), "err", err)
return nil, err
}
// Fill in deposits if we are the first block of the epoch
var deposits []hexutil.Bytes
if seqNumber == 0 {
var errs []error
deposits, errs = DeriveDeposits(receipts, aq.config.DepositContractAddress)
for _, err := range errs {
aq.log.Error("Failed to derive a deposit", "l1Origin", batch.Epoch(), "err", err)
}
if len(errs) != 0 {
// TODO: Multierror here
return nil, fmt.Errorf("failed to derive some deposits: %v", errs)
if crit {
return fmt.Errorf("failed to prepare payload attributes for batch: %v", err)
} else {
aq.log.Error("temporarily failing to prepare payload attributes for batch", "err", err)
return nil
}
}
var txns []eth.Data
l1InfoTx, err := L1InfoDepositBytes(seqNumber, l1Info)
if err != nil {
return nil, fmt.Errorf("failed to create l1InfoTx: %w", err)
}
txns = append(txns, l1InfoTx)
if seqNumber == 0 {
txns = append(txns, deposits...)
}
txns = append(txns, batch.Transactions...)
attrs := &eth.PayloadAttributes{
Timestamp: hexutil.Uint64(batch.Timestamp),
PrevRandao: eth.Bytes32(l1Info.MixDigest()),
SuggestedFeeRecipient: aq.config.FeeRecipientAddress,
Transactions: txns,
// we are verifying, not sequencing, we've got all transactions and do not pull from the tx-pool
// (that would make the block derivation non-deterministic)
NoTxPool: true,
}
aq.log.Info("generated attributes in payload queue", "tx_count", len(txns), "timestamp", batch.Timestamp)
attrs.NoTxPool = true
attrs.Transactions = append(attrs.Transactions, batch.Transactions...)
aq.log.Info("generated attributes in payload queue", "txs", len(attrs.Transactions), "timestamp", batch.Timestamp)
// Slice off the batch once we are guaranteed to succeed
aq.batches = aq.batches[1:]
return attrs, nil
aq.next.AddSafeAttributes(attrs)
return nil
}
func (aq *AttributesQueue) ResetStep(ctx context.Context, l1Fetcher L1Fetcher) error {
aq.batches = aq.batches[:0]
aq.progress = aq.next.Progress()
return io.EOF
}
func (aq *AttributesQueue) SafeL2Head() eth.L2BlockRef {
return aq.next.SafeL2Head()
}
package derive
import (
"context"
"io"
"math/big"
"math/rand"
"testing"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
type MockAttributesQueueOutput struct {
MockOriginStage
}
func (m *MockAttributesQueueOutput) AddSafeAttributes(attributes *eth.PayloadAttributes) {
m.Mock.MethodCalled("AddSafeAttributes", attributes)
}
func (m *MockAttributesQueueOutput) ExpectAddSafeAttributes(attributes *eth.PayloadAttributes) {
m.Mock.On("AddSafeAttributes", attributes).Once().Return()
}
func (m *MockAttributesQueueOutput) SafeL2Head() eth.L2BlockRef {
return m.Mock.MethodCalled("SafeL2Head").Get(0).(eth.L2BlockRef)
}
func (m *MockAttributesQueueOutput) ExpectSafeL2Head(head eth.L2BlockRef) {
m.Mock.On("SafeL2Head").Once().Return(head)
}
var _ AttributesQueueOutput = (*MockAttributesQueueOutput)(nil)
func TestAttributesQueue_Step(t *testing.T) {
// test config, only init the necessary fields
cfg := &rollup.Config{
BlockTime: 2,
L1ChainID: big.NewInt(101),
L2ChainID: big.NewInt(102),
FeeRecipientAddress: common.Address{0xaa},
DepositContractAddress: common.Address{0xbb},
}
rng := rand.New(rand.NewSource(1234))
l1Info := testutils.RandomL1Info(rng)
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l1Fetcher.ExpectInfoByHash(l1Info.InfoHash, l1Info, nil)
out := &MockAttributesQueueOutput{}
out.progress = Progress{
Origin: l1Info.BlockRef(),
Closed: false,
}
defer out.AssertExpectations(t)
safeHead := testutils.RandomL2BlockRef(rng)
safeHead.L1Origin = l1Info.ID()
out.ExpectSafeL2Head(safeHead)
batch := &BatchData{BatchV1{
EpochNum: rollup.Epoch(l1Info.InfoNum),
EpochHash: l1Info.InfoHash,
Timestamp: 12345,
Transactions: []eth.Data{eth.Data("foobar"), eth.Data("example")},
}}
l1InfoTx, err := L1InfoDepositBytes(safeHead.SequenceNumber+1, l1Info)
require.NoError(t, err)
attrs := eth.PayloadAttributes{
Timestamp: eth.Uint64Quantity(safeHead.Time + cfg.BlockTime),
PrevRandao: eth.Bytes32(l1Info.InfoMixDigest),
SuggestedFeeRecipient: cfg.FeeRecipientAddress,
Transactions: []eth.Data{l1InfoTx, eth.Data("foobar"), eth.Data("example")},
NoTxPool: true,
}
out.ExpectAddSafeAttributes(&attrs)
aq := NewAttributesQueue(testlog.Logger(t, log.LvlError), cfg, l1Fetcher, out)
require.NoError(t, RepeatResetStep(t, aq.ResetStep, l1Fetcher, 1))
aq.AddBatch(batch)
require.NoError(t, aq.Step(context.Background(), out.progress), "adding batch to next stage, no EOF yet")
require.Equal(t, io.EOF, aq.Step(context.Background(), out.progress), "done with batches")
}
package derive
import (
"context"
"errors"
"fmt"
"math/big"
"math/rand"
"testing"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)
func TestPreparePayloadAttributes(t *testing.T) {
// test config, only init the necessary fields
cfg := &rollup.Config{
BlockTime: 2,
L1ChainID: big.NewInt(101),
L2ChainID: big.NewInt(102),
FeeRecipientAddress: common.Address{0xaa},
DepositContractAddress: common.Address{0xbb},
}
t.Run("inconsistent next height origin", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
epoch := l1Info.ID()
l1Fetcher.ExpectFetch(epoch.Hash, l1Info, nil, nil, nil)
_, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
require.NotNil(t, err, "inconsistent L1 origin error expected")
require.True(t, crit, "inconsistent L1 origin transition must be handled like a critical error with reorg")
})
t.Run("inconsistent equal height origin", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoNum = l2Parent.L1Origin.Number
epoch := l1Info.ID()
_, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
require.NotNil(t, err, "inconsistent L1 origin error expected")
require.True(t, crit, "inconsistent L1 origin transition must be handled like a critical error with reorg")
})
t.Run("rpc fail Fetch", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
epoch := l2Parent.L1Origin
epoch.Number += 1
mockRPCErr := errors.New("mock rpc error")
l1Fetcher.ExpectFetch(epoch.Hash, nil, nil, nil, mockRPCErr)
_, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
require.ErrorIs(t, err, mockRPCErr, "mock rpc error expected")
require.False(t, crit, "rpc errors should not be critical, it is not necessary to reorg")
})
t.Run("rpc fail InfoByHash", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
epoch := l2Parent.L1Origin
mockRPCErr := errors.New("mock rpc error")
l1Fetcher.ExpectInfoByHash(epoch.Hash, nil, mockRPCErr)
_, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
require.ErrorIs(t, err, mockRPCErr, "mock rpc error expected")
require.False(t, crit, "rpc errors should not be critical, it is not necessary to reorg")
})
t.Run("next origin without deposits", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoParentHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(0, l1Info)
require.NoError(t, err)
l1Fetcher.ExpectFetch(epoch.Hash, l1Info, nil, nil, nil)
attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
require.NoError(t, err)
require.False(t, crit)
require.NotNil(t, attrs)
require.Equal(t, l2Parent.Time+cfg.BlockTime, uint64(attrs.Timestamp))
require.Equal(t, eth.Bytes32(l1Info.InfoMixDigest), attrs.PrevRandao)
require.Equal(t, cfg.FeeRecipientAddress, attrs.SuggestedFeeRecipient)
require.Equal(t, 1, len(attrs.Transactions))
require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0]))
require.True(t, attrs.NoTxPool)
})
t.Run("next origin with deposits", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoParentHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number + 1
receipts, depositTxs := makeReceipts(rng, l1Info.InfoHash, cfg.DepositContractAddress, []receiptData{
{goodReceipt: true, DepositLogs: []bool{true, false}},
{goodReceipt: true, DepositLogs: []bool{true}},
{goodReceipt: false, DepositLogs: []bool{true}},
{goodReceipt: false, DepositLogs: []bool{false}},
})
usedDepositTxs, err := encodeDeposits(depositTxs)
require.NoError(t, err)
epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(0, l1Info)
require.NoError(t, err)
l2Txs := append(append(make([]eth.Data, 0), l1InfoTx), usedDepositTxs...)
// txs are ignored, API is a bit bloated to previous approach. Only l1Info and receipts matter.
l1Txs := make(types.Transactions, len(receipts))
l1Fetcher.ExpectFetch(epoch.Hash, l1Info, l1Txs, receipts, nil)
attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
require.NoError(t, err)
require.False(t, crit)
require.NotNil(t, attrs)
require.Equal(t, l2Parent.Time+cfg.BlockTime, uint64(attrs.Timestamp))
require.Equal(t, eth.Bytes32(l1Info.InfoMixDigest), attrs.PrevRandao)
require.Equal(t, cfg.FeeRecipientAddress, attrs.SuggestedFeeRecipient)
require.Equal(t, len(l2Txs), len(attrs.Transactions), "Expected txs to equal l1 info tx + user deposit txs")
require.Equal(t, l2Txs, attrs.Transactions)
require.True(t, attrs.NoTxPool)
})
t.Run("same origin again", func(t *testing.T) {
rng := rand.New(rand.NewSource(1234))
l1Fetcher := &testutils.MockL1Source{}
defer l1Fetcher.AssertExpectations(t)
l2Parent := testutils.RandomL2BlockRef(rng)
l1Info := testutils.RandomL1Info(rng)
l1Info.InfoHash = l2Parent.L1Origin.Hash
l1Info.InfoNum = l2Parent.L1Origin.Number
epoch := l1Info.ID()
l1InfoTx, err := L1InfoDepositBytes(l2Parent.SequenceNumber+1, l1Info)
require.NoError(t, err)
l1Fetcher.ExpectInfoByHash(epoch.Hash, l1Info, nil)
attrs, crit, err := PreparePayloadAttributes(context.Background(), cfg, l1Fetcher, l2Parent, epoch)
require.NoError(t, err)
require.False(t, crit)
require.NotNil(t, attrs)
require.Equal(t, l2Parent.Time+cfg.BlockTime, uint64(attrs.Timestamp))
require.Equal(t, eth.Bytes32(l1Info.InfoMixDigest), attrs.PrevRandao)
require.Equal(t, cfg.FeeRecipientAddress, attrs.SuggestedFeeRecipient)
require.Equal(t, 1, len(attrs.Transactions))
require.Equal(t, l1InfoTx, []byte(attrs.Transactions[0]))
require.True(t, attrs.NoTxPool)
})
}
func encodeDeposits(deposits []*types.DepositTx) (out []eth.Data, err error) {
for i, tx := range deposits {
opaqueTx, err := types.NewTx(tx).MarshalBinary()
if err != nil {
return nil, fmt.Errorf("bad deposit %d: %v", i, err)
}
out = append(out, opaqueTx)
}
return
}
......@@ -6,8 +6,10 @@ import (
"testing"
"github.com/ethereum-optimism/optimism/op-node/testutils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestUnmarshalLogEvent(t *testing.T) {
......@@ -43,32 +45,9 @@ type receiptData struct {
DepositLogs []bool
}
type DeriveUserDepositsTestCase struct {
name string
// generate len(receipts) receipts
receipts []receiptData
}
func TestDeriveUserDeposits(t *testing.T) {
testCases := []DeriveUserDepositsTestCase{
{"no deposits", []receiptData{}},
{"other log", []receiptData{{true, []bool{false}}}},
{"success deposit", []receiptData{{true, []bool{true}}}},
{"failed deposit", []receiptData{{false, []bool{true}}}},
{"mixed deposits", []receiptData{{true, []bool{true}}, {false, []bool{true}}}},
{"success multiple logs", []receiptData{{true, []bool{true, true}}}},
{"failed multiple logs", []receiptData{{false, []bool{true, true}}}},
{"not all deposit logs", []receiptData{{true, []bool{true, false, true}}}},
{"random", []receiptData{{true, []bool{false, false, true}}, {false, []bool{}}, {true, []bool{true}}}},
}
for i, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
rng := rand.New(rand.NewSource(1234 + int64(i)))
var receipts []*types.Receipt
var expectedDeposits []*types.DepositTx
func makeReceipts(rng *rand.Rand, blockHash common.Hash, depositContractAddr common.Address, testReceipts []receiptData) (receipts []*types.Receipt, expectedDeposits []*types.DepositTx) {
logIndex := uint(0)
blockHash := testutils.RandomHash(rng)
for txIndex, rData := range testCase.receipts {
for txIndex, rData := range testReceipts {
var logs []*types.Log
status := types.ReceiptStatusSuccessful
if !rData.goodReceipt {
......@@ -82,7 +61,7 @@ func TestDeriveUserDeposits(t *testing.T) {
if status == types.ReceiptStatusSuccessful {
expectedDeposits = append(expectedDeposits, dep)
}
ev = MarshalDepositLogEvent(MockDepositContractAddr, dep)
ev = MarshalDepositLogEvent(depositContractAddr, dep)
} else {
ev = testutils.GenerateLog(testutils.RandomAddress(rng), nil, nil)
}
......@@ -101,12 +80,38 @@ func TestDeriveUserDeposits(t *testing.T) {
TransactionIndex: uint(txIndex),
})
}
got, errs := UserDeposits(receipts, MockDepositContractAddr)
assert.Equal(t, len(errs), 0)
assert.Equal(t, len(got), len(expectedDeposits))
return
}
type DeriveUserDepositsTestCase struct {
name string
// generate len(receipts) receipts
receipts []receiptData
}
func TestDeriveUserDeposits(t *testing.T) {
testCases := []DeriveUserDepositsTestCase{
{"no deposits", []receiptData{}},
{"other log", []receiptData{{true, []bool{false}}}},
{"success deposit", []receiptData{{true, []bool{true}}}},
{"failed deposit", []receiptData{{false, []bool{true}}}},
{"mixed deposits", []receiptData{{true, []bool{true}}, {false, []bool{true}}}},
{"success multiple logs", []receiptData{{true, []bool{true, true}}}},
{"failed multiple logs", []receiptData{{false, []bool{true, true}}}},
{"not all deposit logs", []receiptData{{true, []bool{true, false, true}}}},
{"random", []receiptData{{true, []bool{false, false, true}}, {false, []bool{}}, {true, []bool{true}}}},
}
for i, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
rng := rand.New(rand.NewSource(1234 + int64(i)))
blockHash := testutils.RandomHash(rng)
receipts, expectedDeposits := makeReceipts(rng, blockHash, MockDepositContractAddr, testCase.receipts)
got, err := UserDeposits(receipts, MockDepositContractAddr)
require.NoError(t, err)
require.Equal(t, len(got), len(expectedDeposits))
for d, depTx := range got {
expected := expectedDeposits[d]
assert.Equal(t, expected, depTx)
require.Equal(t, expected, depTx)
}
})
}
......
......@@ -3,16 +3,17 @@ package derive
import (
"fmt"
"github.com/hashicorp/go-multierror"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
)
// UserDeposits transforms the L2 block-height and L1 receipts into the transaction inputs for a full L2 block
func UserDeposits(receipts []*types.Receipt, depositContractAddr common.Address) ([]*types.DepositTx, []error) {
func UserDeposits(receipts []*types.Receipt, depositContractAddr common.Address) ([]*types.DepositTx, error) {
var out []*types.DepositTx
var errs []error
var result error
for i, rec := range receipts {
if rec.Status != types.ReceiptStatusSuccessful {
continue
......@@ -21,26 +22,30 @@ func UserDeposits(receipts []*types.Receipt, depositContractAddr common.Address)
if log.Address == depositContractAddr && len(log.Topics) > 0 && log.Topics[0] == DepositEventABIHash {
dep, err := UnmarshalDepositLogEvent(log)
if err != nil {
errs = append(errs, fmt.Errorf("malformatted L1 deposit log in receipt %d, log %d: %w", i, j, err))
result = multierror.Append(result, fmt.Errorf("malformatted L1 deposit log in receipt %d, log %d: %w", i, j, err))
} else {
out = append(out, dep)
}
}
}
}
return out, errs
return out, result
}
func DeriveDeposits(receipts []*types.Receipt, depositContractAddr common.Address) ([]hexutil.Bytes, []error) {
userDeposits, errs := UserDeposits(receipts, depositContractAddr)
func DeriveDeposits(receipts []*types.Receipt, depositContractAddr common.Address) ([]hexutil.Bytes, error) {
var result error
userDeposits, err := UserDeposits(receipts, depositContractAddr)
if err != nil {
result = multierror.Append(result, err)
}
encodedTxs := make([]hexutil.Bytes, 0, len(userDeposits))
for i, tx := range userDeposits {
opaqueTx, err := types.NewTx(tx).MarshalBinary()
if err != nil {
errs = append(errs, fmt.Errorf("failed to encode user tx %d", i))
result = multierror.Append(result, fmt.Errorf("failed to encode user tx %d", i))
} else {
encodedTxs = append(encodedTxs, opaqueTx)
}
}
return encodedTxs, errs
return encodedTxs, result
}
......@@ -9,8 +9,6 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
......@@ -27,70 +25,16 @@ func (d *outputImpl) createNewBlock(ctx context.Context, l2Head eth.L2BlockRef,
fetchCtx, cancel := context.WithTimeout(ctx, time.Second*20)
defer cancel()
var l1Info eth.L1Info
var receipts types.Receipts
var err error
seqNumber := l2Head.SequenceNumber + 1
// If the L1 origin changed this block, then we are in the first block of the epoch. In this
// case we need to fetch all transaction receipts from the L1 origin block so we can scan for
// user deposits.
if l2Head.L1Origin.Number != l1Origin.Number {
if l2Head.L1Origin.Hash != l1Origin.ParentHash {
d.log.Error("SEQUENCING BUG: cannot create new block on top of l2Head with new origin", "head", l2Head,
"head_origin", l2Head.L1Origin, "head_seq_nr", l2Head.SequenceNumber, "new_origin", l1Origin, "new_origin_parent", l1Origin.ParentID())
return l2Head, nil, fmt.Errorf("cannot create new block with L1 origin %s (parent %s) on top of L1 origin %s", l1Origin, l1Origin.ParentID(), l2Head.L1Origin)
}
l1Info, _, receipts, err = d.dl.Fetch(fetchCtx, l1Origin.Hash)
seqNumber = 0 // reset sequence number at the start of the epoch
} else {
if l2Head.L1Origin.Hash != l1Origin.Hash {
d.log.Error("SEQUENCING BUG: cannot create new block on top of l2Head with different origin at same height",
"head", l2Head, "head_origin", l2Head.L1Origin, "head_seq_nr", l2Head.SequenceNumber, "new_origin", l1Origin, "new_origin_parent", l1Origin.ParentID())
return l2Head, nil, fmt.Errorf("cannot create new block with L1 origin %s (parent %s) on top of L1 origin %s", l1Origin, l1Origin.ParentID(), l2Head.L1Origin)
}
l1Info, err = d.dl.InfoByHash(fetchCtx, l1Origin.Hash)
}
if err != nil {
return l2Head, nil, fmt.Errorf("failed to fetch L1 block info of %s: %v", l1Origin, err)
}
// Start building the list of transactions to include in the new block.
var txns []eth.Data
// First transaction in every block is always the L1 info transaction.
l1InfoTx, err := derive.L1InfoDepositBytes(seqNumber, l1Info)
attrs, _, err := derive.PreparePayloadAttributes(fetchCtx, d.Config, d.dl, l2Head, l1Origin.ID())
if err != nil {
return l2Head, nil, err
}
txns = append(txns, l1InfoTx)
// Next we append user deposits. If we're not the first block in an epoch, then receipts will
// be empty and no deposits will be derived.
deposits, errs := derive.DeriveDeposits(receipts, d.Config.DepositContractAddress)
d.log.Info("Derived deposits", "deposits", deposits, "l2Parent", l2Head, "l1Origin", l1Origin)
for _, err := range errs {
d.log.Error("Failed to derive a deposit", "l1OriginHash", l1Origin.Hash, "err", err)
}
// TODO: Should we halt if len(errs) > 0? Opens up a denial of service attack, but prevents lockup of funds.
txns = append(txns, deposits...)
// If our next L2 block timestamp is beyond the Sequencer drift threshold, then we must produce
// empty blocks (other than the L1 info deposit and any user deposits). We handle this by
// setting NoTxPool to true, which will cause the Sequencer to not include any transactions
// from the transaction pool.
nextL2Time := l2Head.Time + d.Config.BlockTime
shouldProduceEmptyBlock := nextL2Time >= l1Origin.Time+d.Config.MaxSequencerDrift
// Put together our payload attributes.
attrs := &eth.PayloadAttributes{
Timestamp: hexutil.Uint64(nextL2Time),
PrevRandao: eth.Bytes32(l1Info.MixDigest()),
SuggestedFeeRecipient: d.Config.FeeRecipientAddress,
Transactions: txns,
NoTxPool: shouldProduceEmptyBlock,
}
attrs.NoTxPool = uint64(attrs.Timestamp) >= l1Origin.Time+d.Config.MaxSequencerDrift
// And construct our fork choice state. This is our current fork choice state and will be
// updated as a result of executing the block based on the attributes described above.
......
......@@ -13,6 +13,15 @@ type MockL1Source struct {
mock.Mock
}
func (m *MockL1Source) InfoByHash(ctx context.Context, hash common.Hash) (eth.L1Info, error) {
out := m.Mock.MethodCalled("InfoByHash", hash)
return *out[0].(*eth.L1Info), *out[1].(*error)
}
func (m *MockL1Source) ExpectInfoByHash(hash common.Hash, info eth.L1Info, err error) {
m.Mock.On("InfoByHash", hash).Once().Return(&info, &err)
}
func (m *MockL1Source) L1BlockRefByNumber(ctx context.Context, u uint64) (eth.L1BlockRef, error) {
out := m.Mock.MethodCalled("L1BlockRefByNumber", u)
return out[0].(eth.L1BlockRef), *out[1].(*error)
......@@ -33,11 +42,11 @@ func (m *MockL1Source) ExpectL1BlockRefByHash(hash common.Hash, ref eth.L1BlockR
func (m *MockL1Source) Fetch(ctx context.Context, blockHash common.Hash) (eth.L1Info, types.Transactions, types.Receipts, error) {
out := m.Mock.MethodCalled("Fetch", blockHash)
return out[0].(eth.L1Info), out[1].(types.Transactions), out[2].(types.Receipts), *out[3].(*error)
return *out[0].(*eth.L1Info), out[1].(types.Transactions), out[2].(types.Receipts), *out[3].(*error)
}
func (m *MockL1Source) ExpectFetch(hash common.Hash, info eth.L1Info, transactions types.Transactions, receipts types.Receipts, err error) {
m.Mock.On("Fetch", hash).Once().Return(info, transactions, receipts, &err)
m.Mock.On("Fetch", hash).Once().Return(&info, transactions, receipts, &err)
}
func (m *MockL1Source) InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.L1Info, types.Transactions, error) {
......
......@@ -2,6 +2,8 @@ FROM golang:1.18.0-alpine3.15 as builder
RUN apk add --no-cache make gcc musl-dev linux-headers git jq bash
# build op-proposer with local monorepo go modules
COPY ./op-proposer/docker.go.work /app/go.work
COPY ./op-bindings /app/op-bindings
COPY ./op-node /app/op-node
COPY ./op-proposer /app/op-proposer
......
go 1.18
use (
./op-bindings
./op-node
./op-proposer
)
......@@ -3,8 +3,8 @@ module github.com/ethereum-optimism/optimism/op-proposer
go 1.18
require (
github.com/ethereum-optimism/optimism/op-bindings v0.0.0
github.com/ethereum-optimism/optimism/op-node v0.0.0
github.com/ethereum-optimism/optimism/op-bindings v0.3.0
github.com/ethereum-optimism/optimism/op-node v0.3.0
github.com/ethereum/go-ethereum v1.10.17
github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/stretchr/testify v1.8.0
......@@ -60,8 +60,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/ethereum-optimism/optimism/op-node v0.0.0 => ../op-node
replace github.com/ethereum-optimism/optimism/op-bindings v0.0.0 => ../op-bindings
replace github.com/ethereum/go-ethereum v1.10.17 => github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d
......@@ -191,6 +191,10 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum-optimism/optimism/op-bindings v0.0.0-20220614233543-0d8fa52afca2/go.mod h1:e9mMYiVsdJf9BI//FdaA77BwNNgNMR043JtB7CPXNxY=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0 h1:d2Mwb8FzR2zuhW0sS5xFKWz/6VFPTEIE+XINqZj0Rv4=
github.com/ethereum-optimism/optimism/op-bindings v0.3.0/go.mod h1:CrvUVIISKcyJ7o27ub/HY4Kq9wEJQxrGmWthTqxPSGo=
github.com/ethereum-optimism/optimism/op-node v0.3.0 h1:jep/cbIbP7fjBSAR48yk5NJVEoGYvoNlYI00KpBI6Mw=
github.com/ethereum-optimism/optimism/op-node v0.3.0/go.mod h1:iF9AhYjr8jNeoCDNP/Vs/ywQ2USZU5L66AxZbSAUi0E=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d h1:AYFFbxrz7kLyFbvNHGhUPZQT8KnN1PPjCj4oAcgaVCk=
github.com/ethereum-optimism/reference-optimistic-geth v0.0.0-20220711171946-f579014dc46d/go.mod h1:8AfU1epKggKxDt9wr7rH5KmCeiT3yT0sEvroru1mO6Q=
github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg=
......
......@@ -79,7 +79,7 @@ fi
(
cd ops-bedrock
echo "Bringing up L1..."
DOCKER_BUILDKIT=1 docker-compose build
DOCKER_BUILDKIT=1 docker-compose build --progress plain
docker-compose up -d l1
wait_up $L1_URL
)
......
......@@ -42,7 +42,7 @@ services:
- l2
build:
context: ../
dockerfile: ./ops-bedrock/Dockerfile.node
dockerfile: ./op-node/Dockerfile
command: >
op-node
--l1=ws://l1:8546
......@@ -81,7 +81,7 @@ services:
- op-node
build:
context: ../
dockerfile: ./ops-bedrock/Dockerfile.proposer
dockerfile: ./op-proposer/Dockerfile
environment:
L1_ETH_RPC: http://l1:8545
L2_ETH_RPC: http://l2:8545
......@@ -102,7 +102,7 @@ services:
- op-node
build:
context: ../
dockerfile: ./ops-bedrock/Dockerfile.batcher
dockerfile: ./op-batcher/Dockerfile
environment:
L1_ETH_RPC: http://l1:8545
L2_ETH_RPC: http://l2:8545
......
# @eth-optimism/ci-builder
## 0.1.2
### Patch Changes
- 184f13b6: Retrigger release of ci-builder
## 0.1.1
### Patch Changes
- 7bf30513: Fix publishing
- a60502f9: Install new version of bash
## 0.1.0
### Minor Changes
- 8c121ece: Update foundry in ci builder
### Patch Changes
- 445efe9d: Use ethereumoptimism/foundry:latest
......@@ -13,7 +13,7 @@ COPY --from=geth /usr/local/bin/abigen /usr/local/bin/abigen
COPY check-changed.sh /usr/local/bin/check-changed
RUN apt-get update && \
apt-get install -y curl openssh-client git build-essential ca-certificates jq musl && \
apt-get install -y bash curl openssh-client git build-essential ca-certificates jq musl && \
curl -sL https://deb.nodesource.com/setup_16.x -o nodesource_setup.sh && \
curl -sL https://go.dev/dl/go1.18.2.linux-amd64.tar.gz -o go1.18.2.linux-amd64.tar.gz && \
tar -C /usr/local/ -xzvf go1.18.2.linux-amd64.tar.gz && \
......@@ -51,4 +51,8 @@ RUN echo "downloading solidity compilers" && \
mkdir -p ~/.svm/0.8.10 && \
cp solc-linux-amd64-v0.8.10+commit.fc410830 ~/.svm/0.8.10/solc-0.8.10 && \
mkdir -p ~/.svm/0.8.12 && \
cp solc-linux-amd64-v0.8.12+commit.f00d7308 ~/.svm/0.8.12/solc-0.8.12
cp solc-linux-amd64-v0.8.12+commit.f00d7308 ~/.svm/0.8.12/solc-0.8.12 && \
rm solc-linux-amd64-v0.5.17+commit.d19bba13 && \
rm solc-linux-amd64-v0.8.9+commit.e5eed63a && \
rm solc-linux-amd64-v0.8.10+commit.fc410830 && \
rm solc-linux-amd64-v0.8.12+commit.f00d7308
{
"name": "@eth-optimism/ci-builder",
"version": "0.0.0",
"version": "0.1.2",
"scripts": {},
"license": "MIT",
"dependencies": {}
......
# @eth-optimism/foundry
## 0.1.0
### Minor Changes
- 5ae9c133: Initial release, pin to b7b1ec471bdd38221773e1a569dc4f20297bd7db
### Patch Changes
- d4de18ea: Use alpine:3.14
{
"name": "@eth-optimism/foundry",
"version": "0.0.0",
"version": "0.1.0",
"scripts": {},
"license": "MIT",
"dependencies": {}
}
# @eth-optimism/common-ts
## 0.6.1
### Patch Changes
- Updated dependencies [f9fee446]
- @eth-optimism/core-utils@0.9.1
## 0.6.0
### Minor Changes
......
{
"name": "@eth-optimism/common-ts",
"version": "0.6.0",
"version": "0.6.1",
"description": "[Optimism] Advanced typescript tooling used by various services",
"main": "dist/index",
"types": "dist/index",
......@@ -32,7 +32,7 @@
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"dependencies": {
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/core-utils": "0.9.1",
"@sentry/node": "^6.3.1",
"bcfg": "^0.1.7",
"body-parser": "^1.20.0",
......
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_0() (gas: 158608)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_1() (gas: 75017)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 249829)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 116083)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 249851)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 116058)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_0() (gas: 158650)
GasBenchMark_L1CrossDomainMessenger:test_L1MessengerSendMessage_benchmark_1() (gas: 75059)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 249871)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 116125)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 249893)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 116100)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 45413)
GasBenchMark_L2OutputOracle:test_appendL2Output_benchmark() (gas: 68673)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 75069)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 35373)
DeployerWhitelist_Test:test_owner() (gas: 7658)
DeployerWhitelist_Test:test_storageSlots() (gas: 33494)
Encoding_Test:test_encodeDepositTransaction() (gas: 64610)
GasPriceOracle_Test:test_baseFee() (gas: 8370)
GasPriceOracle_Test:test_gasPrice() (gas: 8381)
GasPriceOracle_Test:test_l1BaseFee() (gas: 10582)
......@@ -23,7 +24,8 @@ GasPriceOracle_Test:test_setL1BaseFeeReverts() (gas: 11717)
GasPriceOracle_Test:test_setOverhead() (gas: 36767)
GasPriceOracle_Test:test_setScalar() (gas: 36818)
GasPriceOracle_Test:test_storageLayout() (gas: 86683)
Hashing_Test:test_l2TransactionHash() (gas: 104047)
Hashing_Test:test_hashDepositSource() (gas: 673)
Hashing_Test:test_hashDepositTransaction() (gas: 39129)
L1BlockTest:test_basefee() (gas: 7531)
L1BlockTest:test_hash() (gas: 7575)
L1BlockTest:test_number() (gas: 7630)
......@@ -35,20 +37,20 @@ L1BlockNumberTest:test_getL1BlockNumber() (gas: 10657)
L1BlockNumberTest:test_receive() (gas: 25437)
L1CrossDomainMessenger_Test:testCannot_L1MessengerPause() (gas: 24517)
L1CrossDomainMessenger_Test:testCannot_L1MessengerUnpause() (gas: 24509)
L1CrossDomainMessenger_Test:test_L1MessengerMessageVersion() (gas: 24671)
L1CrossDomainMessenger_Test:test_L1MessengerMessageVersion() (gas: 24716)
L1CrossDomainMessenger_Test:test_L1MessengerPause() (gas: 47995)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77935)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 67946)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageSucceeds() (gas: 77773)
L1CrossDomainMessenger_Test:test_L1MessengerRelayMessageToSystemContract() (gas: 67784)
L1CrossDomainMessenger_Test:test_L1MessengerRelayShouldRevertIfPaused() (gas: 60472)
L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 196861)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1273524)
L1CrossDomainMessenger_Test:test_L1MessengerSendMessage() (gas: 196878)
L1CrossDomainMessenger_Test:test_L1MessengerTwiceSendMessage() (gas: 1273626)
L1CrossDomainMessenger_Test:test_L1MessengerUnpause() (gas: 40890)
L1CrossDomainMessenger_Test:test_L1MessengerXDomainSenderReverts() (gas: 24272)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86782)
L1StandardBridge_Test:test_depositERC20() (gas: 474966)
L1StandardBridge_Test:test_depositERC20To() (gas: 477147)
L1StandardBridge_Test:test_depositETH() (gas: 268899)
L1StandardBridge_Test:test_depositETHTo() (gas: 226721)
L1CrossDomainMessenger_Test:test_L1MessengerxDomainMessageSenderResets() (gas: 86701)
L1StandardBridge_Test:test_depositERC20() (gas: 475008)
L1StandardBridge_Test:test_depositERC20To() (gas: 477189)
L1StandardBridge_Test:test_depositETH() (gas: 268941)
L1StandardBridge_Test:test_depositETHTo() (gas: 226763)
L1StandardBridge_Test:test_finalizeERC20Withdrawal() (gas: 490759)
L1StandardBridge_Test:test_finalizeETHWithdrawal() (gas: 64409)
L1StandardBridge_Test:test_initialize() (gas: 26336)
......@@ -56,17 +58,17 @@ L1StandardBridge_Test:test_onlyEOADepositERC20() (gas: 22363)
L1StandardBridge_Test:test_onlyEOADepositETH() (gas: 40882)
L1StandardBridge_Test:test_onlyL2BridgeFinalizeERC20Withdrawal() (gas: 36271)
L1StandardBridge_Test:test_onlyPortalFinalizeERC20Withdrawal() (gas: 35600)
L1StandardBridge_Test:test_receive() (gas: 413479)
L1StandardBridge_Test:test_receive() (gas: 413521)
L2CrossDomainMessenger_Test:testCannot_L2MessengerPause() (gas: 10821)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8400)
L2CrossDomainMessenger_Test:test_L2MessengerMessageVersion() (gas: 8445)
L2CrossDomainMessenger_Test:test_L2MessengerPause() (gas: 31815)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57494)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36221)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageSucceeds() (gas: 57332)
L2CrossDomainMessenger_Test:test_L2MessengerRelayMessageToSystemContract() (gas: 36140)
L2CrossDomainMessenger_Test:test_L2MessengerRelayShouldRevertIfPaused() (gas: 41664)
L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 119619)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133146)
L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 119627)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 133248)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10599)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54925)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 54844)
L2OutputOracleTest:testCannot_AppendWithUnmatchedBlockhash() (gas: 26811)
L2OutputOracleTest:testCannot_appendEmptyOutput() (gas: 24086)
L2OutputOracleTest:testCannot_appendFutureTimetamp() (gas: 26075)
......@@ -90,14 +92,14 @@ L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 8476)
L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 13497)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38865)
L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 230843)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133158)
L2StandardBridge_Test:test_ERC20BridgeFailed_whenLocalTokenIsBridge() (gas: 133200)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21656)
L2StandardBridge_Test:test_finalizeDeposit() (gas: 93203)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140168)
L2StandardBridge_Test:test_finalizeDeposit_failsToCompleteOutboundTransfer() (gas: 140210)
L2StandardBridge_Test:test_initialize() (gas: 14802)
L2StandardBridge_Test:test_receive() (gas: 136483)
L2StandardBridge_Test:test_withdraw() (gas: 352780)
L2StandardBridge_Test:test_withdrawTo() (gas: 353464)
L2StandardBridge_Test:test_receive() (gas: 136525)
L2StandardBridge_Test:test_withdraw() (gas: 352813)
L2StandardBridge_Test:test_withdrawTo() (gas: 353498)
L2StandardBridge_Test:test_withdraw_onlyEOA() (gas: 252006)
L2ToL1MessagePasserTest:test_burn() (gas: 112037)
L2ToL1MessagePasserTest:test_initiateWithdrawal_fromContract() (gas: 67892)
......@@ -252,13 +254,13 @@ RLPWriter_Test:test_writeUint_smallint3() (gas: 7372)
RLPWriter_Test:test_writeUint_smallint4() (gas: 7351)
RLPWriter_Test:test_writeUint_zero() (gas: 7798)
ResourceMetering_Test:test_initialResourceParams() (gas: 8964)
ResourceMetering_Test:test_updateNoGasDelta() (gas: 2008269)
ResourceMetering_Test:test_updateOneEmptyBlock() (gas: 18123)
ResourceMetering_Test:test_updateParamsNoChange() (gas: 13860)
ResourceMetering_Test:test_updateTenEmptyBlocks() (gas: 20523)
ResourceMetering_Test:test_updateTwoEmptyBlocks() (gas: 20546)
ResourceMetering_Test:test_useMaxSucceeds() (gas: 8017023)
ResourceMetering_Test:test_useMoreThanMaxReverts() (gas: 16002)
ResourceMetering_Test:test_updateNoGasDelta() (gas: 2008317)
ResourceMetering_Test:test_updateOneEmptyBlock() (gas: 18171)
ResourceMetering_Test:test_updateParamsNoChange() (gas: 13956)
ResourceMetering_Test:test_updateTenEmptyBlocks() (gas: 20571)
ResourceMetering_Test:test_updateTwoEmptyBlocks() (gas: 20594)
ResourceMetering_Test:test_useMaxSucceeds() (gas: 8017119)
ResourceMetering_Test:test_useMoreThanMaxReverts() (gas: 16047)
Semver_Test:test_behindProxy() (gas: 504908)
Semver_Test:test_major() (gas: 5406)
Semver_Test:test_minor() (gas: 5430)
......@@ -267,4 +269,4 @@ SequencerFeeVault_Test:test_constructor() (gas: 7656)
SequencerFeeVault_Test:test_minWithdrawalAmount() (gas: 5407)
SequencerFeeVault_Test:test_receive() (gas: 17258)
SequencerFeeVault_Test:test_revertWithdraw() (gas: 9332)
SequencerFeeVault_Test:test_withdraw() (gas: 147281)
SequencerFeeVault_Test:test_withdraw() (gas: 147323)
......@@ -31,7 +31,7 @@
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| xDomainMsgSender | address | 202 | 0 | 20 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| msgNonce | uint256 | 203 | 0 | 32 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
| msgNonce | uint240 | 203 | 0 | 30 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| otherMessenger | address | 204 | 0 | 20 | contracts/L1/L1CrossDomainMessenger.sol:L1CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
......@@ -192,7 +192,7 @@
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| xDomainMsgSender | address | 202 | 0 | 20 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| msgNonce | uint256 | 203 | 0 | 32 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
| msgNonce | uint240 | 203 | 0 | 30 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
| otherMessenger | address | 204 | 0 | 20 | contracts/L2/L2CrossDomainMessenger.sol:L2CrossDomainMessenger |
|------------------------+--------------------------+------+--------+-------+----------------------------------------------------------------|
......
# @eth-optimism/contracts-bedrock
## 0.5.0
### Minor Changes
- 42a4cc30: Remove Lib* and OVM* prefixes from all contracts
### Patch Changes
- 0cb3929e: Move encoding and hashing into Encoding and Hashing libraries
- 28bd76ae: Cleans up hashing and encoding library natspec and function names
- 4279647f: Port RLPWriter tests
- ce6cb121: Use external version of ExcessivelySafeCall
- 8986f165: Fix solc warnings in ProxyAdmin
- 69ee689f: Remove unnecessary DefaultValues library
- 2e89f634: Fixes a bug that caused L2 timestamps to be computed incorrectly
- 49d33b08: Standardizes comments, errors, and events for contracts in the /universal package
- 821907e2: Bump typechain to 8.1.0
- 91b31168: Clean up comments and errors for legacy contracts
- 3c5726d4: Cleaned up enums, should be CapitalCase enums and UPPER_CASE values
- eb11a5bb: Add comments to RLP libraries
- 092b0901: Update to new L2 tx hash style for deposits
- 4ea33e13: Standardizes initialization logic for L1 contracts
- 297af083: Move contracts written by external parties into a vendor folder
- 71800503: Reduce the number of compiler warnings
- 611d93a1: Remove storage slot buffer in xdomain messengers
- 75089d0a: Cleans up initialization logic everywhere
- b9a90f32: Rename OptimismMintableTokenFactory to OptimismMintableERC20Factory
- 50e20ea1: Fix initialization logic
- 6f74ca9f: Clean up the PredeployAddresses library
- c031ec95: Tests for RLPReader
- 9c8b1f00: Bump forge-std to 62caef29b0f87a2c6aaaf634b2ca4c09b6867c92
- 89d01f2e: Add semver to L2 contracts
- 7d9820b6: Resolve compiler warnings in Proxy.sol
- f9fee446: Move the `DepositTx` type to `core-utils`. This way it can be more easily used across projects
- 5050e0fb: Remove "not implemented" errors in virtual functions
- 78d7c2ec: Update typechain pipeline
- 89d01f2e: Update dev deps
- Updated dependencies [f9fee446]
- @eth-optimism/core-utils@0.9.1
## 0.4.1
### Patch Changes
......
......@@ -2,8 +2,7 @@
## Install
The repo currently uses a mix of typescript tests (run with HardHat) and solidity tests (run with Forge). The project
uses the default hardhat directory structure, and all build/test steps should be run using the yarn scripts to ensure
The repo currently uses solidity tests (run with Forge). The project uses the default hardhat directory structure, and all build/test steps should be run using the yarn scripts to ensure
the correct options are set.
Install node modules with yarn (v1), and Node.js (14+).
......@@ -22,28 +21,12 @@ yarn build
## Running Tests
First get the dependencies:
`git submodule init` and `git submodule update`
Then the full test suite can be executed via `yarn`:
```shell
yarn test
```
To run only typescript tests:
```shell
yarn test:hh
```
To run only solidity tests:
```shell
yarn test:forge
```
## Deployment
Create a file that corresponds to the network name in the `deploy-config`
......@@ -52,7 +35,7 @@ directory and then run the command:
```shell
L1_RPC=<ETHEREUM L1 RPC endpoint> \
PRIVATE_KEY_DEPLOYER=<PRIVATE KEY TO PAY FOR THE DEPLOYMENT> \
npx hardhat deploy --network <network-name>
npx hardhat deploy --network <network-name>
```
In the `hardhat.config.ts`, there is a `deployConfigSpec` field that validates that the types
......
......@@ -86,6 +86,8 @@ contract L1StandardBridge is StandardBridge, Semver {
);
/**
* @custom:semver 0.0.1
*
* @param _messenger Address of the L1CrossDomainMessenger.
*/
constructor(address payable _messenger) Semver(0, 0, 1) {
......
......@@ -99,12 +99,11 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
constructor(L2OutputOracle _l2Oracle, uint256 _finalizationPeriodSeconds) Semver(0, 0, 1) {
L2_ORACLE = _l2Oracle;
FINALIZATION_PERIOD_SECONDS = _finalizationPeriodSeconds;
initialize();
}
/**
* @notice Intializes mutable variables.
* @notice Initializer;
*/
function initialize() public initializer {
l2Sender = DEFAULT_L2_SENDER;
......@@ -242,13 +241,13 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// Verify that the output root can be generated with the elements in the proof.
require(
proposal.outputRoot == Hashing._deriveOutputRoot(_outputRootProof),
proposal.outputRoot == Hashing.hashOutputRootProof(_outputRootProof),
"OptimismPortal: invalid output root proof"
);
// All withdrawals have a unique hash, we'll use this as the identifier for the withdrawal
// and to prevent replay attacks.
bytes32 withdrawalHash = Hashing.withdrawalHash(
bytes32 withdrawalHash = Hashing.hashWithdrawal(
_nonce,
_sender,
_target,
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { SignedMath } from "@openzeppelin/contracts/utils/math/SignedMath.sol";
import { FixedPointMathLib } from "@rari-capital/solmate/src/utils/FixedPointMathLib.sol";
......@@ -11,7 +12,7 @@ import { Burn } from "../libraries/Burn.sol";
* @notice ResourceMetering implements an EIP-1559 style resource metering system where pricing
* updates automatically based on current demand.
*/
contract ResourceMetering {
abstract contract ResourceMetering is Initializable {
/**
* @notice Represents the various parameters that control the way in which resources are
* metered. Corresponds to the EIP-1559 resource metering system.
......@@ -62,19 +63,11 @@ contract ResourceMetering {
*/
uint256[49] private __gap;
/**
* @notice Set the initial values. In order to enable this contract to be used in an upgradable
* context, the constructor calls a separate init function.
*/
constructor() {
__ResourceMetering_init();
}
/**
* @notice Sets initial resource parameter values. This function must either be called by the
* initializer function of an upgradeable child contract.
*/
function __ResourceMetering_init() internal {
function __ResourceMetering_init() internal onlyInitializing {
params = ResourceParams({
prevBaseFee: INITIAL_BASE_FEE,
prevBoughtGas: 0,
......
......@@ -79,7 +79,7 @@ contract L2ToL1MessagePasser is Semver {
uint256 _gasLimit,
bytes memory _data
) public payable {
bytes32 withdrawalHash = Hashing.withdrawalHash(
bytes32 withdrawalHash = Hashing.hashWithdrawal(
nonce,
msg.sender,
_target,
......
......@@ -10,73 +10,58 @@ import { RLPWriter } from "./rlp/RLPWriter.sol";
*/
library Encoding {
/**
* Generates the correct cross domain calldata for a message.
* @param _target Target contract address.
* @param _sender Message sender address.
* @param _message Message to send to the target.
* @param _messageNonce Nonce for the provided message.
* @return ABI encoded cross domain calldata.
* @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
* to the L2 system. Useful for searching for a deposit in the L2 system.
*
* @param _from Address of the sender of the deposit.
* @param _to Address of the receiver of the deposit.
* @param _value ETH value to send to the receiver.
* @param _mint ETH value to mint on L2.
* @param _gasLimit Gas limit to use for the transaction.
* @param _isCreation Whether or not the transaction is a contract creation.
* @param _data Data to send with the transaction.
* @param _l1BlockHash Hash of the L1 block where the deposit was included.
* @param _logIndex Index of the deposit event in the L1 block.
*
* @return RLP encoded L2 deposit transaction.
*/
function encodeXDomainCalldata(
address _target,
address _sender,
bytes memory _message,
uint256 _messageNonce
) internal pure returns (bytes memory) {
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_message,
_messageNonce
);
}
/**
* @notice RLP encode a deposit transaction
* This only works for user deposits, not system deposits
* TODO: better name + rearrange the input param ordering?
*/
function L2Transaction(
bytes32 _l1BlockHash,
uint256 _logIndex,
function encodeDepositTransaction(
address _from,
address _to,
bool _isCreate,
uint256 _mint,
uint256 _value,
uint256 _gas,
bytes memory _data
uint256 _mint,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data,
bytes32 _l1BlockHash,
uint256 _logIndex
) internal pure returns (bytes memory) {
bytes32 source = Hashing.sourceHash(_l1BlockHash, _logIndex);
bytes32 source = Hashing.hashDepositSource(_l1BlockHash, _logIndex);
bytes[] memory raw = new bytes[](7);
raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
raw[1] = RLPWriter.writeAddress(_from);
if (_isCreate == true) {
require(_to == address(0));
raw[2] = RLPWriter.writeBytes("");
} else {
raw[2] = RLPWriter.writeAddress(_to);
}
raw[2] = _isCreation ? RLPWriter.writeBytes("") : RLPWriter.writeAddress(_to);
raw[3] = RLPWriter.writeUint(_mint);
raw[4] = RLPWriter.writeUint(_value);
raw[5] = RLPWriter.writeUint(_gas);
raw[5] = RLPWriter.writeUint(uint256(_gasLimit));
raw[6] = RLPWriter.writeBytes(_data);
bytes memory encoded = RLPWriter.writeList(raw);
return abi.encodePacked(uint8(0x7e), uint8(0x0), encoded);
return abi.encodePacked(uint8(0x7e), uint8(0x0), RLPWriter.writeList(raw));
}
/**
* @notice Encodes the cross domain message based on the version that
* is encoded in the nonce
* @notice Encodes the cross domain message based on the version that is encoded into the
* message nonce.
*
* @param _nonce Message nonce with version encoded into the first two bytes.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Encoded cross domain message.
*/
function getVersionedEncoding(
function encodeCrossDomainMessage(
uint256 _nonce,
address _sender,
address _target,
......@@ -84,32 +69,55 @@ library Encoding {
uint256 _gasLimit,
bytes memory _data
) internal pure returns (bytes memory) {
uint16 version = getVersionFromNonce(_nonce);
(, uint16 version) = decodeVersionedNonce(_nonce);
if (version == 0) {
return getEncodingV0(_target, _sender, _data, _nonce);
return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);
} else if (version == 1) {
return getEncodingV1(_nonce, _sender, _target, _value, _gasLimit, _data);
return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);
} else {
revert("Encoding: unknown cross domain message version");
}
revert("Unknown version.");
}
/**
* @notice Compute the legacy cross domain serialization
* @notice Encodes a cross domain message based on the V0 (legacy) encoding.
*
* @param _target Address of the target of the message.
* @param _sender Address of the sender of the message.
* @param _data Data to send with the message.
* @param _nonce Message nonce.
*
* @return Encoded cross domain message.
*/
function getEncodingV0(
function encodeCrossDomainMessageV0(
address _target,
address _sender,
bytes memory _data,
uint256 _nonce
) internal pure returns (bytes memory) {
return encodeXDomainCalldata(_target, _sender, _data, _nonce);
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_data,
_nonce
);
}
/**
* @notice Compute the V1 cross domain serialization
* @notice Encodes a cross domain message based on the V1 (current) encoding.
*
* @param _nonce Message nonce.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Encoded cross domain message.
*/
function getEncodingV1(
function encodeCrossDomainMessageV1(
uint256 _nonce,
address _sender,
address _target,
......@@ -130,24 +138,36 @@ library Encoding {
}
/**
* @notice Adds the version to the nonce
* @notice Adds a version number into the first two bytes of a message nonce.
*
* @param _nonce Message nonce to encode into.
* @param _version Version number to encode into the message nonce.
*
* @return Message nonce with version encoded into the first two bytes.
*/
function addVersionToNonce(uint256 _nonce, uint16 _version)
internal
pure
returns (uint256 nonce)
{
function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {
uint256 nonce;
assembly {
nonce := or(shl(240, _version), _nonce)
}
return nonce;
}
/**
* @notice Gets the version out of the nonce
* @notice Pulls the version out of a version-encoded nonce.
*
* @param _nonce Message nonce with version encoded into the first two bytes.
*
* @return Nonce without encoded version.
* @return Version of the message.
*/
function getVersionFromNonce(uint256 _nonce) internal pure returns (uint16 version) {
function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {
uint240 nonce;
uint16 version;
assembly {
nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
version := shr(240, _nonce)
}
return (nonce, version);
}
}
......@@ -8,7 +8,10 @@ import { Encoding } from "./Encoding.sol";
* @notice Hashing handles Optimism's various different hashing schemes.
*/
library Hashing {
/// @notice A struct containing the elements hashed together to generate the output root.
/**
* @notice Struct representing the elements that are hashed together to generate an output root
* which itself represents a snapshot of the L2 state.
*/
struct OutputRootProof {
bytes32 version;
bytes32 stateRoot;
......@@ -17,66 +20,81 @@ library Hashing {
}
/**
* @notice Compute the L2 transaction hash given
* data about an L1 deposit transaction. This is useful for
* environments that do not have access to arbitrary
* RLP encoding functionality but have access to the
* standard web3 API
* TODO: rearrange args in a sane way
* @param _l1BlockHash The L1 block hash corresponding to the block
* the deposit was included in
* @param _logIndex The log index of the event that the deposit was
* created from. This can be found on the transaction receipt
* @param _from The sender of the deposit
* @param _to The L2 contract to be called by the deposit transaction
* @param _isCreate Indicates if the deposit creates a contract
* @param _mint The amount of ETH being minted by the transaction
* @param _value The amount of ETH send in the L2 call
* @param _gas The gas limit for the L2 call
* @notice Computes the hash of the RLP encoded L2 transaction that would be generated when a
* given deposit is sent to the L2 system. Useful for searching for a deposit in the L2
* system.
*
* @param _from Address of the sender of the deposit.
* @param _to Address of the receiver of the deposit.
* @param _value ETH value to send to the receiver.
* @param _mint ETH value to mint on L2.
* @param _gasLimit Gas limit to use for the transaction.
* @param _isCreation Whether or not the transaction is a contract creation.
* @param _data Data to send with the transaction.
* @param _l1BlockHash Hash of the L1 block where the deposit was included.
* @param _logIndex Index of the deposit event in the L1 block.
*
* @return Hash of the RLP encoded L2 deposit transaction.
*/
function L2TransactionHash(
bytes32 _l1BlockHash,
uint256 _logIndex,
function hashDepositTransaction(
address _from,
address _to,
bool _isCreate,
uint256 _mint,
uint256 _value,
uint256 _gas,
bytes memory _data
uint256 _mint,
uint64 _gasLimit,
bool _isCreation,
bytes memory _data,
bytes32 _l1BlockHash,
uint256 _logIndex
) internal pure returns (bytes32) {
bytes memory raw = Encoding.L2Transaction(
_l1BlockHash,
_logIndex,
bytes memory raw = Encoding.encodeDepositTransaction(
_from,
_to,
_isCreate,
_mint,
_value,
_gas,
_data
_mint,
_gasLimit,
_isCreation,
_data,
_l1BlockHash,
_logIndex
);
return keccak256(raw);
}
/**
* @notice Compute the deposit transaction source hash.
* This value ensures that the L2 transaction hash is unique
* and deterministic based on L1 execution
* @param l1BlockHash The L1 blockhash corresponding to the block including
* the deposit
* @param logIndex The index of the log that created the deposit transaction
* @notice Computes the deposit transaction's "source hash", a value that guarantees the hash
* of the L2 transaction that corresponds to a deposit is unique and is
* deterministically generated from L1 transaction data.
*
* @param _l1BlockHash Hash of the L1 block where the deposit was included.
* @param _logIndex The index of the log that created the deposit transaction.
*
* @return Hash of the deposit transaction's "source hash".
*/
function sourceHash(bytes32 l1BlockHash, uint256 logIndex) internal pure returns (bytes32) {
bytes32 depositId = keccak256(abi.encode(l1BlockHash, logIndex));
function hashDepositSource(bytes32 _l1BlockHash, uint256 _logIndex)
internal
pure
returns (bytes32)
{
bytes32 depositId = keccak256(abi.encode(_l1BlockHash, _logIndex));
return keccak256(abi.encode(bytes32(0), depositId));
}
/**
* @notice Compute the cross domain hash based on the versioned nonce
* @notice Hashes the cross domain message based on the version that is encoded into the
* message nonce.
*
* @param _nonce Message nonce with version encoded into the first two bytes.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Hashed cross domain message.
*/
function getVersionedHash(
function hashCrossDomainMessage(
uint256 _nonce,
address _sender,
address _target,
......@@ -84,32 +102,48 @@ library Hashing {
uint256 _gasLimit,
bytes memory _data
) internal pure returns (bytes32) {
uint16 version = Encoding.getVersionFromNonce(_nonce);
(, uint16 version) = Encoding.decodeVersionedNonce(_nonce);
if (version == 0) {
return getHashV0(_target, _sender, _data, _nonce);
return hashCrossDomainMessageV0(_target, _sender, _data, _nonce);
} else if (version == 1) {
return getHashV1(_nonce, _sender, _target, _value, _gasLimit, _data);
return hashCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);
} else {
revert("Hashing: unknown cross domain message version");
}
revert("Unknown version.");
}
/**
* @notice Compute the legacy hash of a cross domain message
* @notice Hashes a cross domain message based on the V0 (legacy) encoding.
*
* @param _target Address of the target of the message.
* @param _sender Address of the sender of the message.
* @param _data Data to send with the message.
* @param _nonce Message nonce.
*
* @return Hashed cross domain message.
*/
function getHashV0(
function hashCrossDomainMessageV0(
address _target,
address _sender,
bytes memory _data,
uint256 _nonce
) internal pure returns (bytes32) {
return keccak256(Encoding.getEncodingV0(_target, _sender, _data, _nonce));
return keccak256(Encoding.encodeCrossDomainMessageV0(_target, _sender, _data, _nonce));
}
/**
* @notice Compute the V1 hash of a cross domain message
* @notice Hashes a cross domain message based on the V1 (current) encoding.
*
* @param _nonce Message nonce.
* @param _sender Address of the sender of the message.
* @param _target Address of the target of the message.
* @param _value ETH value to send to the target.
* @param _gasLimit Gas limit to use for the message.
* @param _data Data to send with the message.
*
* @return Hashed cross domain message.
*/
function getHashV1(
function hashCrossDomainMessageV1(
uint256 _nonce,
address _sender,
address _target,
......@@ -118,7 +152,16 @@ library Hashing {
bytes memory _data
) internal pure returns (bytes32) {
return
keccak256(Encoding.getEncodingV1(_nonce, _sender, _target, _value, _gasLimit, _data));
keccak256(
Encoding.encodeCrossDomainMessageV1(
_nonce,
_sender,
_target,
_value,
_gasLimit,
_data
)
);
}
/**
......@@ -130,7 +173,7 @@ library Hashing {
* @param _gasLimit Gas to be forwarded to the target.
* @param _data Data to send to the target.
*/
function withdrawalHash(
function hashWithdrawal(
uint256 _nonce,
address _sender,
address _target,
......@@ -142,11 +185,14 @@ library Hashing {
}
/**
* @notice Derives the output root corresponding to the elements provided in the proof.
* @param _outputRootProof The elements which were hashed together to generate the output root.
* @return Whether or not the output root matches the hashed output of the proof.
* @notice Hashes the various elements of an output root proof into an output root hash which
* can be used to check if the proof is valid.
*
* @param _outputRootProof Output root proof which should hash to an output root.
*
* @return Hashed output root proof.
*/
function _deriveOutputRoot(OutputRootProof memory _outputRootProof)
function hashOutputRootProof(OutputRootProof memory _outputRootProof)
internal
pure
returns (bytes32)
......
......@@ -2,41 +2,42 @@
pragma solidity ^0.8.9;
/**
* @custom:attribution https://github.com/hamdiallam/Solidity-RLP
* @title RLPReader
* @dev Adapted from "RLPReader" by Hamdi Allam (hamdi.allam97@gmail.com).
* @notice RLPReader is a library for parsing RLP-encoded byte arrays into Solidity types. Adapted
* from Solidity-RLP (https://github.com/hamdiallam/Solidity-RLP) by Hamdi Allam with
* various tweaks to improve readability.
*/
library RLPReader {
/*************
* Constants *
*************/
/**
* @notice Max list length that this library will accept.
*/
uint256 internal constant MAX_LIST_LENGTH = 32;
/*********
* Enums *
*********/
/**
* @notice RLP item types.
*
* @custom:value DATA_ITEM Represents an RLP data item (NOT a list).
* @custom:value LIST_ITEM Represents an RLP list item.
*/
enum RLPItemType {
DATA_ITEM,
LIST_ITEM
}
/***********
* Structs *
***********/
/**
* @notice Struct representing an RLP item.
*/
struct RLPItem {
uint256 length;
uint256 ptr;
}
/**********************
* Internal Functions *
**********************/
/**
* Converts bytes to a reference to memory position and length.
* @notice Converts bytes to a reference to memory position and length.
*
* @param _in Input bytes to convert.
*
* @return Output memory reference.
*/
function toRLPItem(bytes memory _in) internal pure returns (RLPItem memory) {
......@@ -49,8 +50,10 @@ library RLPReader {
}
/**
* Reads an RLP list value into a list of RLP items.
* @notice Reads an RLP list value into a list of RLP items.
*
* @param _in RLP list value.
*
* @return Decoded RLP list items.
*/
function readList(RLPItem memory _in) internal pure returns (RLPItem[] memory) {
......@@ -88,8 +91,10 @@ library RLPReader {
}
/**
* Reads an RLP list value into a list of RLP items.
* @notice Reads an RLP list value into a list of RLP items.
*
* @param _in RLP list value.
*
* @return Decoded RLP list items.
*/
function readList(bytes memory _in) internal pure returns (RLPItem[] memory) {
......@@ -97,8 +102,10 @@ library RLPReader {
}
/**
* Reads an RLP bytes value into bytes.
* @notice Reads an RLP bytes value into bytes.
*
* @param _in RLP bytes value.
*
* @return Decoded bytes.
*/
function readBytes(RLPItem memory _in) internal pure returns (bytes memory) {
......@@ -110,8 +117,10 @@ library RLPReader {
}
/**
* Reads an RLP bytes value into bytes.
* @notice Reads an RLP bytes value into bytes.
*
* @param _in RLP bytes value.
*
* @return Decoded bytes.
*/
function readBytes(bytes memory _in) internal pure returns (bytes memory) {
......@@ -119,8 +128,10 @@ library RLPReader {
}
/**
* Reads an RLP string value into a string.
* @notice Reads an RLP string value into a string.
*
* @param _in RLP string value.
*
* @return Decoded string.
*/
function readString(RLPItem memory _in) internal pure returns (string memory) {
......@@ -128,8 +139,10 @@ library RLPReader {
}
/**
* Reads an RLP string value into a string.
* @notice Reads an RLP string value into a string.
*
* @param _in RLP string value.
*
* @return Decoded string.
*/
function readString(bytes memory _in) internal pure returns (string memory) {
......@@ -137,8 +150,10 @@ library RLPReader {
}
/**
* Reads an RLP bytes32 value into a bytes32.
* @notice Reads an RLP bytes32 value into a bytes32.
*
* @param _in RLP bytes32 value.
*
* @return Decoded bytes32.
*/
function readBytes32(RLPItem memory _in) internal pure returns (bytes32) {
......@@ -163,8 +178,10 @@ library RLPReader {
}
/**
* Reads an RLP bytes32 value into a bytes32.
* @notice Reads an RLP bytes32 value into a bytes32.
*
* @param _in RLP bytes32 value.
*
* @return Decoded bytes32.
*/
function readBytes32(bytes memory _in) internal pure returns (bytes32) {
......@@ -172,8 +189,10 @@ library RLPReader {
}
/**
* Reads an RLP uint256 value into a uint256.
* @notice Reads an RLP uint256 value into a uint256.
*
* @param _in RLP uint256 value.
*
* @return Decoded uint256.
*/
function readUint256(RLPItem memory _in) internal pure returns (uint256) {
......@@ -181,8 +200,10 @@ library RLPReader {
}
/**
* Reads an RLP uint256 value into a uint256.
* @notice Reads an RLP uint256 value into a uint256.
*
* @param _in RLP uint256 value.
*
* @return Decoded uint256.
*/
function readUint256(bytes memory _in) internal pure returns (uint256) {
......@@ -190,8 +211,10 @@ library RLPReader {
}
/**
* Reads an RLP bool value into a bool.
* @notice Reads an RLP bool value into a bool.
*
* @param _in RLP bool value.
*
* @return Decoded bool.
*/
function readBool(RLPItem memory _in) internal pure returns (bool) {
......@@ -209,8 +232,10 @@ library RLPReader {
}
/**
* Reads an RLP bool value into a bool.
* @notice Reads an RLP bool value into a bool.
*
* @param _in RLP bool value.
*
* @return Decoded bool.
*/
function readBool(bytes memory _in) internal pure returns (bool) {
......@@ -218,8 +243,10 @@ library RLPReader {
}
/**
* Reads an RLP address value into a address.
* @notice Reads an RLP address value into a address.
*
* @param _in RLP address value.
*
* @return Decoded address.
*/
function readAddress(RLPItem memory _in) internal pure returns (address) {
......@@ -233,8 +260,10 @@ library RLPReader {
}
/**
* Reads an RLP address value into a address.
* @notice Reads an RLP address value into a address.
*
* @param _in RLP address value.
*
* @return Decoded address.
*/
function readAddress(bytes memory _in) internal pure returns (address) {
......@@ -242,8 +271,10 @@ library RLPReader {
}
/**
* Reads the raw bytes of an RLP item.
* @notice Reads the raw bytes of an RLP item.
*
* @param _in RLP item to read.
*
* @return Raw RLP bytes.
*/
function readRawBytes(RLPItem memory _in) internal pure returns (bytes memory) {
......@@ -255,8 +286,10 @@ library RLPReader {
*********************/
/**
* Decodes the length of an RLP item.
* @notice Decodes the length of an RLP item.
*
* @param _in RLP item to decode.
*
* @return Offset of the encoded data.
* @return Length of the encoded data.
* @return RLP item type (LIST_ITEM or DATA_ITEM).
......@@ -333,10 +366,12 @@ library RLPReader {
}
/**
* Copies the bytes from a memory location.
* @notice Copies the bytes from a memory location.
*
* @param _src Pointer to the location to read from.
* @param _offset Offset to start reading from.
* @param _length Number of bytes to read.
*
* @return Copied bytes.
*/
function _copy(
......@@ -378,8 +413,10 @@ library RLPReader {
}
/**
* Copies an RLP item into bytes.
* @notice Copies an RLP item into bytes.
*
* @param _in RLP item to copy.
*
* @return Copied bytes.
*/
function _copy(RLPItem memory _in) private pure returns (bytes memory) {
......
......@@ -2,17 +2,18 @@
pragma solidity ^0.8.9;
/**
* @custom:attribution https://github.com/bakaoh/solidity-rlp-encode
* @title RLPWriter
* @author Bakaoh (with modifications)
* @author RLPWriter is a library for encoding Solidity types to RLP bytes. Adapted from Bakaoh's
* RLPEncode library (https://github.com/bakaoh/solidity-rlp-encode) with minor
* modifications to improve legibility.
*/
library RLPWriter {
/**********************
* Internal Functions *
**********************/
/**
* RLP encodes a byte string.
* @notice RLP encodes a byte string.
*
* @param _in The byte string to encode.
*
* @return The RLP encoded string in bytes.
*/
function writeBytes(bytes memory _in) internal pure returns (bytes memory) {
......@@ -28,8 +29,10 @@ library RLPWriter {
}
/**
* RLP encodes a list of RLP encoded byte byte strings.
* @notice RLP encodes a list of RLP encoded byte byte strings.
*
* @param _in The list of RLP encoded byte strings.
*
* @return The RLP encoded list of items in bytes.
*/
function writeList(bytes[] memory _in) internal pure returns (bytes memory) {
......@@ -38,8 +41,10 @@ library RLPWriter {
}
/**
* RLP encodes a string.
* @notice RLP encodes a string.
*
* @param _in The string to encode.
*
* @return The RLP encoded string in bytes.
*/
function writeString(string memory _in) internal pure returns (bytes memory) {
......@@ -47,8 +52,10 @@ library RLPWriter {
}
/**
* RLP encodes an address.
* @notice RLP encodes an address.
*
* @param _in The address to encode.
*
* @return The RLP encoded address in bytes.
*/
function writeAddress(address _in) internal pure returns (bytes memory) {
......@@ -56,8 +63,10 @@ library RLPWriter {
}
/**
* RLP encodes a uint.
* @notice RLP encodes a uint.
*
* @param _in The uint256 to encode.
*
* @return The RLP encoded uint256 in bytes.
*/
function writeUint(uint256 _in) internal pure returns (bytes memory) {
......@@ -65,8 +74,10 @@ library RLPWriter {
}
/**
* RLP encodes a bool.
* @notice RLP encodes a bool.
*
* @param _in The bool to encode.
*
* @return The RLP encoded bool in bytes.
*/
function writeBool(bool _in) internal pure returns (bytes memory) {
......@@ -75,14 +86,12 @@ library RLPWriter {
return encoded;
}
/*********************
* Private Functions *
*********************/
/**
* Encode the first byte, followed by the `len` in binary form if `length` is more than 55.
* @notice Encode the first byte and then the `len` in binary form if `length` is more than 55.
*
* @param _len The length of the string or the payload.
* @param _offset 128 if item is string, 192 if item is list.
*
* @return RLP encoded bytes.
*/
function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {
......@@ -110,9 +119,10 @@ library RLPWriter {
}
/**
* Encode integer in big endian binary form with no leading zeroes.
* @notice TODO: This should be optimized with assembly to save gas costs.
* @notice Encode integer in big endian binary form with no leading zeroes.
*
* @param _x The integer to encode.
*
* @return RLP encoded bytes.
*/
function _toBinary(uint256 _x) private pure returns (bytes memory) {
......@@ -134,8 +144,9 @@ library RLPWriter {
}
/**
* Copies a piece of memory to another location.
* @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol.
* @custom:attribution https://github.com/Arachnid/solidity-stringutils
* @notice Copies a piece of memory to another location.
*
* @param _dest Destination location.
* @param _src Source location.
* @param _len Length of memory to copy.
......@@ -169,9 +180,11 @@ library RLPWriter {
}
/**
* Flattens a list of byte strings into one byte string.
* @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol.
* @custom:attribution https://github.com/sammayo/solidity-rlp-encoder
* @notice Flattens a list of byte strings into one byte string.
*
* @param _list List of byte strings to flatten.
*
* @return The flattened byte string.
*/
function _flatten(bytes[] memory _list) private pure returns (bytes memory) {
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/* Library Imports */
import { BytesUtils } from "../BytesUtils.sol";
import { RLPReader } from "../rlp/RLPReader.sol";
import { RLPWriter } from "../rlp/RLPWriter.sol";
/**
* @title MerkleTrie
* @notice MerkleTrie is a small library for verifying standard Ethereum Merkle-Patricia trie
* inclusion proofs. By default, this library assumes a hexary trie. One can change the
* trie radix constant to support other trie radixes.
*/
library MerkleTrie {
/*******************
* Data Structures *
*******************/
/**
* @notice Struct representing a node in the trie.
*/
struct TrieNode {
bytes encoded;
RLPReader.RLPItem[] decoded;
}
/**********************
* Contract Constants *
**********************/
// TREE_RADIX determines the number of elements per branch node.
/**
* @notice Determines the number of elements per branch node.
*/
uint256 constant TREE_RADIX = 16;
// Branch nodes have TREE_RADIX elements plus an additional `value` slot.
/**
* @notice Branch nodes have TREE_RADIX elements and one value element.
*/
uint256 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;
// Leaf nodes and extension nodes always have two elements, a `path` and a `value`.
/**
* @notice Leaf nodes and extension nodes have two elements, a `path` and a `value`.
*/
uint256 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;
// Prefixes are prepended to the `path` within a leaf or extension node and
// allow us to differentiate between the two node types. `ODD` or `EVEN` is
// determined by the number of nibbles within the unprefixed `path`. If the
// number of nibbles if even, we need to insert an extra padding nibble so
// the resulting prefixed `path` has an even number of nibbles.
/**
* @notice Prefix for even-nibbled extension node paths.
*/
uint8 constant PREFIX_EXTENSION_EVEN = 0;
/**
* @notice Prefix for odd-nibbled extension node paths.
*/
uint8 constant PREFIX_EXTENSION_ODD = 1;
/**
* @notice Prefix for even-nibbled leaf node paths.
*/
uint8 constant PREFIX_LEAF_EVEN = 2;
/**
* @notice Prefix for odd-nibbled leaf node paths.
*/
uint8 constant PREFIX_LEAF_ODD = 3;
// Just a utility constant. RLP represents `NULL` as 0x80.
/**
* @notice RLP representation of `NULL`.
*/
bytes1 constant RLP_NULL = bytes1(0x80);
/**********************
* Internal Functions *
**********************/
/**
* @notice Verifies a proof that a given key/value pair is present in the
* Merkle trie.
* @notice Verifies a proof that a given key/value pair is present in the trie.
*
* @param _key Key of the node to search for, as a hex string.
* @param _value Value of the node to search for, as a hex string.
* @param _proof Merkle trie inclusion proof for the desired node. Unlike
* traditional Merkle trees, this proof is executed top-down and consists
* of a list of RLP-encoded nodes that make a path down to the target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.
* @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle
* trees, this proof is executed top-down and consists of a list of RLP-encoded
* nodes that make a path down to the target node.
* @param _root Known root of the Merkle trie. Used to verify that the included proof is
* correctly constructed.
*
* @return Whether or not the proof is valid.
*/
function verifyInclusionProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
) internal pure returns (bool _verified) {
) internal pure returns (bool) {
(bool exists, bytes memory value) = get(_key, _proof, _root);
return (exists && BytesUtils.equal(_value, value));
}
/**
* @notice Retrieves the value associated with a given key.
*
* @param _key Key to search for, as hex bytes.
* @param _proof Merkle trie inclusion proof for the key.
* @param _root Known root of the Merkle trie.
* @return _exists Whether or not the key exists.
* @return _value Value of the key if it exists.
*
* @return Whether or not the key exists.
* @return Value of the key if it exists.
*/
function get(
bytes memory _key,
bytes memory _proof,
bytes32 _root
) internal pure returns (bool _exists, bytes memory _value) {
) internal pure returns (bool, bytes memory) {
TrieNode[] memory proof = _parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(
proof,
......@@ -99,18 +114,16 @@ library MerkleTrie {
return (exists, value);
}
/*********************
* Private Functions *
*********************/
/**
* @notice Walks through a proof using a provided key.
*
* @param _proof Inclusion proof to walk through.
* @param _key Key to use for the walk.
* @param _root Known root of the trie.
* @return _pathLength Length of the final path
* @return _keyRemainder Portion of the key remaining after the walk.
* @return _isFinalNode Whether or not we've hit a dead end.
*
* @return Length of the final path
* @return Portion of the key remaining after the walk.
* @return Whether or not we've hit a dead end.
*/
function _walkNodePath(
TrieNode[] memory _proof,
......@@ -120,9 +133,9 @@ library MerkleTrie {
private
pure
returns (
uint256 _pathLength,
bytes memory _keyRemainder,
bool _isFinalNode
uint256,
bytes memory,
bool
)
{
uint256 pathLength = 0;
......@@ -223,10 +236,12 @@ library MerkleTrie {
/**
* @notice Parses an RLP-encoded proof into something more useful.
*
* @param _proof RLP-encoded proof to parse.
* @return _parsed Proof parsed into easily accessible structs.
*
* @return Proof parsed into easily accessible structs.
*/
function _parseProof(bytes memory _proof) private pure returns (TrieNode[] memory _parsed) {
function _parseProof(bytes memory _proof) private pure returns (TrieNode[] memory) {
RLPReader.RLPItem[] memory nodes = RLPReader.readList(_proof);
TrieNode[] memory proof = new TrieNode[](nodes.length);
......@@ -239,13 +254,14 @@ library MerkleTrie {
}
/**
* @notice Picks out the ID for a node. Node ID is referred to as the
* "hash" within the specification, but nodes < 32 bytes are not actually
* hashed.
* @notice Picks out the ID for a node. Node ID is referred to as the "hash" within the
* specification, but nodes < 32 bytes are not actually hashed.
*
* @param _node Node to pull an ID for.
* @return _nodeID ID for the node, depending on the size of its contents.
*
* @return ID for the node, depending on the size of its contents.
*/
function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes32 _nodeID) {
function _getNodeID(RLPReader.RLPItem memory _node) private pure returns (bytes32) {
bytes memory nodeID;
if (_node.length < 32) {
......@@ -261,33 +277,38 @@ library MerkleTrie {
/**
* @notice Gets the path for a leaf or extension node.
*
* @param _node Node to get a path for.
* @return _path Node path, converted to an array of nibbles.
*
* @return Node path, converted to an array of nibbles.
*/
function _getNodePath(TrieNode memory _node) private pure returns (bytes memory _path) {
function _getNodePath(TrieNode memory _node) private pure returns (bytes memory) {
return BytesUtils.toNibbles(RLPReader.readBytes(_node.decoded[0]));
}
/**
* @notice Gets the path for a node.
*
* @param _node Node to get a value for.
* @return _value Node value, as hex bytes.
*
* @return Node value, as hex bytes.
*/
function _getNodeValue(TrieNode memory _node) private pure returns (bytes memory _value) {
function _getNodeValue(TrieNode memory _node) private pure returns (bytes memory) {
return RLPReader.readBytes(_node.decoded[_node.decoded.length - 1]);
}
/**
* @notice Utility; determines the number of nibbles shared between two
* nibble arrays.
* @notice Utility; determines the number of nibbles shared between two nibble arrays.
*
* @param _a First nibble array.
* @param _b Second nibble array.
* @return _shared Number of shared nibbles.
*
* @return Number of shared nibbles.
*/
function _getSharedNibbleLength(bytes memory _a, bytes memory _b)
private
pure
returns (uint256 _shared)
returns (uint256)
{
uint256 i = 0;
while (_a.length > i && _b.length > i && _a[i] == _b[i]) {
......
......@@ -6,61 +6,60 @@ import { MerkleTrie } from "./MerkleTrie.sol";
/**
* @title SecureMerkleTrie
* @notice SecureMerkleTrie is a thin wrapper around the MerkleTrie library that hashes the input
* keys. Ethereum's state trie hashes input keys before storing them.
*/
library SecureMerkleTrie {
/**********************
* Internal Functions *
**********************/
/**
* @notice Verifies a proof that a given key/value pair is present in the
* Merkle trie.
* @notice Verifies a proof that a given key/value pair is present in the Merkle trie.
*
* @param _key Key of the node to search for, as a hex string.
* @param _value Value of the node to search for, as a hex string.
* @param _proof Merkle trie inclusion proof for the desired node. Unlike
* traditional Merkle trees, this proof is executed top-down and consists
* of a list of RLP-encoded nodes that make a path down to the target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.
* @param _proof Merkle trie inclusion proof for the desired node. Unlike traditional Merkle
* trees, this proof is executed top-down and consists of a list of RLP-encoded
* nodes that make a path down to the target node.
* @param _root Known root of the Merkle trie. Used to verify that the included proof is
* correctly constructed.
*
* @return Whether or not the proof is valid.
*/
function verifyInclusionProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
) internal pure returns (bool _verified) {
) internal pure returns (bool) {
bytes memory key = _getSecureKey(_key);
return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);
}
/**
* @notice Retrieves the value associated with a given key.
*
* @param _key Key to search for, as hex bytes.
* @param _proof Merkle trie inclusion proof for the key.
* @param _root Known root of the Merkle trie.
* @return _exists Whether or not the key exists.
* @return _value Value of the key if it exists.
*
* @return Whether or not the key exists.
* @return Value of the key if it exists.
*/
function get(
bytes memory _key,
bytes memory _proof,
bytes32 _root
) internal pure returns (bool _exists, bytes memory _value) {
) internal pure returns (bool, bytes memory) {
bytes memory key = _getSecureKey(_key);
return MerkleTrie.get(key, _proof, _root);
}
/*********************
* Private Functions *
*********************/
/**
* Computes the secure counterpart to a key.
* @param _key Key to get a secure key from.
* @return _secureKey Secure version of the key.
* @notice Computes the hashed version of the input key.
*
* @param _key Key to hash.
*
* @return Hashed version of the key.
*/
function _getSecureKey(bytes memory _key) private pure returns (bytes memory _secureKey) {
function _getSecureKey(bytes memory _key) private pure returns (bytes memory) {
return abi.encodePacked(keccak256(_key));
}
}
......@@ -6,8 +6,29 @@ import { Encoding } from "../libraries/Encoding.sol";
contract Encoding_Test is CommonTest {
function test_nonceVersioning(uint240 _nonce, uint16 _version) external {
uint256 nonce = Encoding.addVersionToNonce(uint256(_nonce), _version);
uint16 version = Encoding.getVersionFromNonce(nonce);
(uint240 nonce, uint16 version) = Encoding.decodeVersionedNonce(
Encoding.encodeVersionedNonce(_nonce, _version)
);
assertEq(version, _version);
assertEq(nonce, _nonce);
}
function test_encodeDepositTransaction() external {
bytes memory raw = Encoding.encodeDepositTransaction(
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266,
0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244,
0xde0b6b3a7640000,
0xe043da617250000,
0x2dc6c0,
false,
hex"",
0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,
0x1
);
assertEq(
raw,
hex"7e00f862a0f923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc94f39fd6e51aad88f6f4ce6ab8827279cfffb9226694b79f76ef2c5f0286176833e7b2eee103b1cc3244880e043da617250000880de0b6b3a7640000832dc6c080"
);
}
}
......@@ -8,54 +8,29 @@ import { Encoding } from "../libraries/Encoding.sol";
contract Hashing_Test is CommonTest {
// TODO(tynes): turn this into differential fuzzing
// it is very easy to do so with the typescript
function test_l2TransactionHash() external {
bytes32 l1BlockHash = 0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959;
uint256 logIndex = 0x1;
address from = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address to = 0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244;
bool isCreate = false;
uint256 mint = 0xe043da617250000;
uint256 value = 0xde0b6b3a7640000;
uint256 gas = 0x2dc6c0;
bytes memory data = hex"";
bytes32 sourceHash = Hashing.sourceHash(
l1BlockHash,
logIndex
function test_hashDepositSource() external {
bytes32 sourceHash = Hashing.hashDepositSource(
0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,
0x1
);
assertEq(
sourceHash,
0xf923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc
);
}
bytes memory raw = Encoding.L2Transaction(
l1BlockHash,
logIndex,
from,
to,
isCreate,
mint,
value,
gas,
data
);
assertEq(
raw,
hex"7e00f862a0f923fb07134d7d287cb52c770cc619e17e82606c21a875c92f4c63b65280a5cc94f39fd6e51aad88f6f4ce6ab8827279cfffb9226694b79f76ef2c5f0286176833e7b2eee103b1cc3244880e043da617250000880de0b6b3a7640000832dc6c080"
);
bytes32 digest = Hashing.L2TransactionHash(
l1BlockHash,
logIndex,
from,
to,
isCreate,
mint,
value,
gas,
data
function test_hashDepositTransaction() external {
bytes32 digest = Hashing.hashDepositTransaction(
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266,
0xB79f76EF2c5F0286176833E7B2eEe103b1CC3244,
0xde0b6b3a7640000,
0xe043da617250000,
0x2dc6c0,
false,
hex"",
0xd25df7858efc1778118fb133ac561b138845361626dfb976699c5287ed0f4959,
0x1
);
assertEq(
......
......@@ -56,8 +56,9 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
// the version is encoded in the nonce
function test_L1MessengerMessageVersion() external {
(,uint16 version) = Encoding.decodeVersionedNonce(L1Messenger.messageNonce());
assertEq(
Encoding.getVersionFromNonce(L1Messenger.messageNonce()),
version,
L1Messenger.MESSAGE_VERSION()
);
}
......@@ -75,7 +76,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
0,
100 + L1Messenger.baseGas(hex"ff"),
false,
Encoding.getVersionedEncoding(
Encoding.encodeCrossDomainMessage(
L1Messenger.messageNonce(),
alice,
recipient,
......@@ -95,7 +96,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
0,
100 + L1Messenger.baseGas(hex"ff"),
false,
Encoding.getVersionedEncoding(
Encoding.encodeCrossDomainMessage(
L1Messenger.messageNonce(),
alice,
recipient,
......@@ -145,7 +146,7 @@ contract L1CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true);
bytes32 hash = Hashing.getVersionedHash(0, sender, target, 0, 0, hex"1111");
bytes32 hash = Hashing.hashCrossDomainMessage(0, sender, target, 0, 0, hex"1111");
emit RelayedMessage(hash);
......
......@@ -31,8 +31,9 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
}
function test_L2MessengerMessageVersion() external {
(, uint16 version) = Encoding.decodeVersionedNonce(L2Messenger.messageNonce());
assertEq(
Encoding.getVersionFromNonce(L2Messenger.messageNonce()),
version,
L2Messenger.MESSAGE_VERSION()
);
}
......@@ -44,7 +45,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
L2ToL1MessagePasser.initiateWithdrawal.selector,
address(L1Messenger),
100 + L2Messenger.baseGas(hex"ff"),
Encoding.getVersionedEncoding(
Encoding.encodeCrossDomainMessage(
L2Messenger.messageNonce(),
alice,
recipient,
......@@ -63,7 +64,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
address(L1Messenger),
0,
100 + L2Messenger.baseGas(hex"ff"),
Encoding.getVersionedEncoding(
Encoding.encodeCrossDomainMessage(
L2Messenger.messageNonce(),
alice,
recipient,
......@@ -104,7 +105,7 @@ contract L2CrossDomainMessenger_Test is Messenger_Initializer {
vm.expectEmit(true, true, true, true);
bytes32 hash = Hashing.getVersionedHash(
bytes32 hash = Hashing.hashCrossDomainMessage(
0,
sender,
target,
......
......@@ -64,7 +64,7 @@ contract L2ToL1MessagePasserTest is CommonTest {
data
);
bytes32 withdrawalHash = Hashing.withdrawalHash(
bytes32 withdrawalHash = Hashing.hashWithdrawal(
nonce,
alice,
target,
......
......@@ -7,6 +7,10 @@ import { Proxy } from "../universal/Proxy.sol";
contract MeterUser is ResourceMetering {
constructor() {
initialize();
}
function initialize() public initializer {
__ResourceMetering_init();
}
......
......@@ -111,7 +111,7 @@ abstract contract CrossDomainMessenger is
* messageNonce getter which will insert the message version into the nonce to give you
* the actual nonce to be used for the message.
*/
uint256 internal msgNonce;
uint240 internal msgNonce;
/**
* @notice Address of the paired CrossDomainMessenger contract on the other chain.
......@@ -172,7 +172,7 @@ abstract contract CrossDomainMessenger is
* @return Nonce of the next message to be sent, with added message version.
*/
function messageNonce() public view returns (uint256) {
return Encoding.addVersionToNonce(msgNonce, MESSAGE_VERSION);
return Encoding.encodeVersionedNonce(msgNonce, MESSAGE_VERSION);
}
/**
......@@ -250,7 +250,7 @@ abstract contract CrossDomainMessenger is
uint256 _minGasLimit,
bytes calldata _message
) external payable nonReentrant whenNotPaused {
bytes32 versionedHash = Hashing.getVersionedHash(
bytes32 versionedHash = Hashing.hashCrossDomainMessage(
_nonce,
_sender,
_target,
......
{
"name": "@eth-optimism/contracts-bedrock",
"version": "0.4.1",
"version": "0.5.0",
"description": "Contracts for Optimism Specs",
"main": "dist/index",
"types": "dist/index",
......@@ -34,7 +34,7 @@
"typechain": "typechain --target ethers-v5 --out-dir dist/types --glob 'artifacts/!(build-info)/**/+([a-zA-Z0-9_]).json'"
},
"dependencies": {
"@eth-optimism/core-utils": "^0.9.0",
"@eth-optimism/core-utils": "^0.9.1",
"@openzeppelin/contracts": "^4.5.0",
"@openzeppelin/contracts-upgradeable": "^4.5.2",
"@rari-capital/solmate": "https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc",
......@@ -49,7 +49,7 @@
"rlp": "^2.2.7"
},
"devDependencies": {
"@eth-optimism/hardhat-deploy-config": "^0.2.0",
"@eth-optimism/hardhat-deploy-config": "^0.2.1",
"@defi-wonderland/smock": "^2.0.2",
"@foundry-rs/hardhat-forge": "^0.1.12",
"@nomiclabs/hardhat-ethers": "^2.0.0",
......
# @eth-optimism/contracts-governance
## 0.1.4
### Patch Changes
- dc9cf2b6: Clean up the hardhat config
- Updated dependencies [f9fee446]
- @eth-optimism/core-utils@0.9.1
- @eth-optimism/sdk@1.2.1
## 0.1.3
### Patch Changes
......
import dotenv from 'dotenv'
import { HardhatUserConfig } from 'hardhat/config'
import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-etherscan'
import '@nomiclabs/hardhat-waffle'
import 'hardhat-gas-reporter'
import 'solidity-coverage'
import { task, types } from 'hardhat/config'
import { providers, utils, Wallet } from 'ethers'
import { CrossChainMessenger } from '@eth-optimism/sdk'
import { getChainId } from '@eth-optimism/core-utils'
import './scripts/deploy-token'
import './scripts/multi-send'
......@@ -17,66 +14,13 @@ import './scripts/create-airdrop-json'
import './scripts/deploy-distributor'
import './scripts/test-claims'
import './scripts/create-distributor-json'
import './scripts/deposit'
dotenv.config()
task('accounts', 'Prints the list of accounts').setAction(async (args, hre) => {
const accounts = await hre.ethers.getSigners()
for (const account of accounts) {
console.log(account.address)
}
})
task('deposit', 'Deposits funds onto Optimism.')
.addParam('to', 'Recipient address.', null, types.string)
.addParam('amountEth', 'Amount in ETH to send.', null, types.string)
.addParam('l1ProviderUrl', '', process.env.L1_PROVIDER_URL, types.string)
.addParam('l2ProviderUrl', '', process.env.L2_PROVIDER_URL, types.string)
.addParam('privateKey', '', process.env.PRIVATE_KEY, types.string)
.setAction(async (args) => {
const { to, amountEth, l1ProviderUrl, l2ProviderUrl, privateKey } = args
if (!l1ProviderUrl || !l2ProviderUrl || !privateKey) {
throw new Error(
'You must define --l1-provider-url, --l2-provider-url, --private-key in your environment.'
)
}
const l1Provider = new providers.JsonRpcProvider(l1ProviderUrl)
const l2Provider = new providers.JsonRpcProvider(l2ProviderUrl)
const l1Wallet = new Wallet(privateKey, l1Provider)
const messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Wallet,
l2SignerOrProvider: l2Provider,
l1ChainId: await getChainId(l1Provider),
l2ChainId: await getChainId(l2Provider),
})
const amountWei = utils.parseEther(amountEth)
console.log(`Depositing ${amountEth} ETH to ${to}...`)
const tx = await messenger.depositETH(amountWei, {
recipient: to,
})
console.log(`Got TX hash ${tx.hash}. Waiting...`)
await tx.wait()
const l1WalletOnL2 = new Wallet(privateKey, l2Provider)
await l1WalletOnL2.sendTransaction({
to,
value: utils.parseEther(amountEth),
})
const balance = await l2Provider.getBalance(to)
console.log('Funded account balance', balance.toString())
console.log('Done.')
})
const privKey = process.env.PRIVATE_KEY || '0x' + '11'.repeat(32)
/**
* @type import("hardhat/config").HardhatUserConfig
*/
module.exports = {
const config: HardhatUserConfig = {
solidity: {
version: '0.8.12',
settings: {
......@@ -91,17 +35,20 @@ module.exports = {
optimism: {
chainId: 17,
url: 'http://localhost:8545',
saveDeployments: false,
},
'optimism-kovan': {
chainId: 69,
url: 'https://kovan.optimism.io',
accounts: [privKey],
},
'optimism-goerli': {
chainId: 420,
url: 'https://goerli.optimism.io',
accounts: [privKey],
},
'optimism-nightly': {
chainId: 421,
url: 'https://goerli-nightly-us-central1-a-sequencer.optimism.io',
saveDeployments: true,
accounts: [privKey],
},
'optimism-mainnet': {
......@@ -110,8 +57,7 @@ module.exports = {
accounts: [privKey],
},
'hardhat-node': {
url: 'http://localhost:9545',
saveDeployments: false,
url: 'http://localhost:8545',
},
},
gasReporter: {
......@@ -122,3 +68,5 @@ module.exports = {
apiKey: process.env.ETHERSCAN_API_KEY,
},
}
export default config
{
"name": "@eth-optimism/contracts-governance",
"version": "0.1.3",
"version": "0.1.4",
"author": "Optimism PBC",
"license": "MIT",
"main": "dist/index",
......@@ -28,8 +28,8 @@
"deploy:mainnet": "hardhat deploy-token --network 'optimism-mainnet'"
},
"dependencies": {
"@eth-optimism/core-utils": "^0.9.0",
"@eth-optimism/sdk": "^1.2.0",
"@eth-optimism/core-utils": "^0.9.1",
"@eth-optimism/sdk": "^1.2.1",
"@ethersproject/hardware-wallets": "^5.6.1",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-etherscan": "^3.0.1",
......
......@@ -93,6 +93,10 @@ task('deploy-token', 'Deploy governance token and its mint manager contracts')
console.log(`Got ${tokenReceipt.contractAddress}`)
throw new Error(`Fatal error! Mismatch of governance token address`)
}
} else if (nonceTokenDeployer !== 0 && governanceTokenCode === '0x') {
throw new Error(
`Nonce is ${nonceTokenDeployer} without governance token deployed`
)
} else {
console.log(
`GovernanceToken already deployed at ${addresses.governanceToken}, skipping`
......
import { task, types } from 'hardhat/config'
import { providers, utils, Wallet } from 'ethers'
import { CrossChainMessenger } from '@eth-optimism/sdk'
import { getChainId } from '@eth-optimism/core-utils'
task('deposit', 'Deposits funds onto Optimism.')
.addParam('to', 'Recipient address.', null, types.string)
.addParam('amountEth', 'Amount in ETH to send.', null, types.string)
.addParam('l1ProviderUrl', '', process.env.L1_PROVIDER_URL, types.string)
.addParam('l2ProviderUrl', '', process.env.L2_PROVIDER_URL, types.string)
.addParam('privateKey', '', process.env.PRIVATE_KEY, types.string)
.setAction(async (args) => {
const { to, amountEth, l1ProviderUrl, l2ProviderUrl, privateKey } = args
if (!l1ProviderUrl || !l2ProviderUrl || !privateKey) {
throw new Error(
'You must define --l1-provider-url, --l2-provider-url, --private-key in your environment.'
)
}
const l1Provider = new providers.JsonRpcProvider(l1ProviderUrl)
const l2Provider = new providers.JsonRpcProvider(l2ProviderUrl)
const l1Wallet = new Wallet(privateKey, l1Provider)
const messenger = new CrossChainMessenger({
l1SignerOrProvider: l1Wallet,
l2SignerOrProvider: l2Provider,
l1ChainId: await getChainId(l1Provider),
l2ChainId: await getChainId(l2Provider),
})
const amountWei = utils.parseEther(amountEth)
console.log(`Depositing ${amountEth} ETH to ${to}...`)
const tx = await messenger.depositETH(amountWei, {
recipient: to,
})
console.log(`Got TX hash ${tx.hash}. Waiting...`)
await tx.wait()
const l1WalletOnL2 = new Wallet(privateKey, l2Provider)
await l1WalletOnL2.sendTransaction({
to,
value: utils.parseEther(amountEth),
})
const balance = await l2Provider.getBalance(to)
console.log('Funded account balance', balance.toString())
console.log('Done.')
})
......@@ -2,6 +2,8 @@ ignores: [
"@eth-optimism/contracts-bedrock",
"@openzeppelin/contracts",
"@openzeppelin/contracts-upgradeable",
"@ethersproject/providers",
"@ethersproject/abi",
"@rari-capital/solmate",
"@types/node",
"hardhat-deploy",
......
# @eth-optimism/contracts-periphery
## 0.2.0
### Minor Changes
- 8a335b7b: Fixes a bug in the OptimismMintableERC721. Requires an interface change, so this is a minor and not patch.
### Patch Changes
- 95fc3fbf: Add typechain with ethers v5 support
- 019657db: Add TeleportrDeposit and TeleportrDisburser to contracts-periphery
- 6ff5c0a3: Cleaned up natspec for Drippie and its dependencies
- 119f0e97: Moves TeleportrWithdrawer to L1 contracts folder
- 9c8b1f00: Bump forge-std to 62caef29b0f87a2c6aaaf634b2ca4c09b6867c92
- 89d01f2e: Update dev deps
## 0.1.5
### Patch Changes
......
......@@ -9,7 +9,7 @@ import {
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { L2ERC721Bridge } from "../../L2/messaging/L2ERC721Bridge.sol";
import { L2ERC721Bridge } from "../L2/L2ERC721Bridge.sol";
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol";
/**
......
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.9;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/**
* @custom:attribution https://github.com/0xclem/teleportr
* @title TeleportrDeposit
* @notice A contract meant to manage deposits into Optimism's Teleportr custodial bridge. Deposits
* are rate limited to avoid a situation where too much ETH is flowing through this bridge
* and cannot be properly disbursed on L2. Inspired by 0xclem's original Teleportr system
* (https://github.com/0xclem/teleportr).
*/
contract TeleportrDeposit is Ownable {
/**
* @notice Minimum deposit amount (in wei).
*/
uint256 public minDepositAmount;
/**
* @notice Maximum deposit amount (in wei).
*/
uint256 public maxDepositAmount;
/**
* @notice Maximum balance this contract will hold before it starts rejecting deposits.
*/
uint256 public maxBalance;
/**
* @notice Total number of deposits received.
*/
uint256 public totalDeposits;
/**
* @notice Emitted any time the minimum deposit amount is set.
*
* @param previousAmount The previous minimum deposit amount.
* @param newAmount The new minimum deposit amount.
*/
event MinDepositAmountSet(uint256 previousAmount, uint256 newAmount);
/**
* @notice Emitted any time the maximum deposit amount is set.
*
* @param previousAmount The previous maximum deposit amount.
* @param newAmount The new maximum deposit amount.
*/
event MaxDepositAmountSet(uint256 previousAmount, uint256 newAmount);
/**
* @notice Emitted any time the contract maximum balance is set.
*
* @param previousBalance The previous maximum contract balance.
* @param newBalance The new maximum contract balance.
*/
event MaxBalanceSet(uint256 previousBalance, uint256 newBalance);
/**
* @notice Emitted any time the balance is withdrawn by the owner.
*
* @param owner The current owner and recipient of the funds.
* @param balance The current contract balance paid to the owner.
*/
event BalanceWithdrawn(address indexed owner, uint256 balance);
/**
* @notice Emitted any time a successful deposit is received.
*
* @param depositId A unique sequencer number identifying the deposit.
* @param emitter The sending address of the payer.
* @param amount The amount deposited by the payer.
*/
event EtherReceived(uint256 indexed depositId, address indexed emitter, uint256 indexed amount);
/**
* @custom:semver 0.0.1
*
* @param _minDepositAmount The initial minimum deposit amount.
* @param _maxDepositAmount The initial maximum deposit amount.
* @param _maxBalance The initial maximum contract balance.
*/
constructor(
uint256 _minDepositAmount,
uint256 _maxDepositAmount,
uint256 _maxBalance
) {
minDepositAmount = _minDepositAmount;
maxDepositAmount = _maxDepositAmount;
maxBalance = _maxBalance;
totalDeposits = 0;
emit MinDepositAmountSet(0, _minDepositAmount);
emit MaxDepositAmountSet(0, _maxDepositAmount);
emit MaxBalanceSet(0, _maxBalance);
}
/**
* @notice Accepts deposits that will be disbursed to the sender's address on L2.
*/
receive() external payable {
require(msg.value >= minDepositAmount, "Deposit amount is too small");
require(msg.value <= maxDepositAmount, "Deposit amount is too big");
require(address(this).balance <= maxBalance, "Contract max balance exceeded");
emit EtherReceived(totalDeposits, msg.sender, msg.value);
unchecked {
totalDeposits += 1;
}
}
/**
* @notice Sends the contract's current balance to the owner.
*/
function withdrawBalance() external onlyOwner {
address _owner = owner();
uint256 _balance = address(this).balance;
emit BalanceWithdrawn(_owner, _balance);
payable(_owner).transfer(_balance);
}
/**
* @notice Sets the minimum amount that can be deposited in a receive.
*
* @param _minDepositAmount The new minimum deposit amount.
*/
function setMinAmount(uint256 _minDepositAmount) external onlyOwner {
emit MinDepositAmountSet(minDepositAmount, _minDepositAmount);
minDepositAmount = _minDepositAmount;
}
/**
* @notice Sets the maximum amount that can be deposited in a receive.
*
* @param _maxDepositAmount The new maximum deposit amount.
*/
function setMaxAmount(uint256 _maxDepositAmount) external onlyOwner {
emit MaxDepositAmountSet(maxDepositAmount, _maxDepositAmount);
maxDepositAmount = _maxDepositAmount;
}
/**
* @notice Sets the maximum balance the contract can hold after a receive.
*
* @param _maxBalance The new maximum contract balance.
*/
function setMaxBalance(uint256 _maxBalance) external onlyOwner {
emit MaxBalanceSet(maxBalance, _maxBalance);
maxBalance = _maxBalance;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import { AssetReceiver } from "./AssetReceiver.sol";
import { AssetReceiver } from "../universal/AssetReceiver.sol";
/**
* @notice Stub interface for Teleportr.
......
......@@ -9,8 +9,8 @@ import {
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { L1ERC721Bridge } from "../../L1/messaging/L1ERC721Bridge.sol";
import { IOptimismMintableERC721 } from "../../universal/op-erc721/IOptimismMintableERC721.sol";
import { L1ERC721Bridge } from "../L1/L1ERC721Bridge.sol";
import { IOptimismMintableERC721 } from "../universal/op-erc721/IOptimismMintableERC721.sol";
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol";
/**
......
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.9;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title TeleportrDisburser
*/
contract TeleportrDisburser is Ownable {
/**
* @notice A struct holding the address and amount to disbursement.
*/
struct Disbursement {
uint256 amount;
address addr;
}
/**
* @notice Total number of disbursements processed.
*/
uint256 public totalDisbursements;
/**
* @notice Emitted any time the balance is withdrawn by the owner.
*
* @param owner The current owner and recipient of the funds.
* @param balance The current contract balance paid to the owner.
*/
event BalanceWithdrawn(address indexed owner, uint256 balance);
/**
* @notice Emitted any time a disbursement is successfuly sent.
*
* @param depositId The unique sequence number identifying the deposit.
* @param to The recipient of the disbursement.
* @param amount The amount sent to the recipient.
*/
event DisbursementSuccess(uint256 indexed depositId, address indexed to, uint256 amount);
/**
* @notice Emitted any time a disbursement fails to send.
*
* @param depositId The unique sequence number identifying the deposit.
* @param to The intended recipient of the disbursement.
* @param amount The amount intended to be sent to the recipient.
*/
event DisbursementFailed(uint256 indexed depositId, address indexed to, uint256 amount);
/**
* @custom:semver 0.0.1
*/
constructor() {
totalDisbursements = 0;
}
/**
* @notice Accepts a list of Disbursements and forwards the amount paid to the contract to each
* recipient. 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 available for the owner to withdraw.
*
* @param _nextDepositId The depositId of the first Dispursement.
* @param _disbursements A list of Disbursements to process.
*/
function disburse(uint256 _nextDepositId, Disbursement[] calldata _disbursements)
external
payable
onlyOwner
{
// Ensure there are disbursements to process.
uint256 _numDisbursements = _disbursements.length;
require(_numDisbursements > 0, "No disbursements");
// Ensure the _nextDepositId matches our expected value.
uint256 _depositId = totalDisbursements;
require(_depositId == _nextDepositId, "Unexpected next deposit id");
unchecked {
totalDisbursements += _numDisbursements;
}
// Ensure the amount sent in the transaction is equal to the sum of the
// disbursements.
uint256 _totalDisbursed = 0;
for (uint256 i = 0; i < _numDisbursements; i++) {
_totalDisbursed += _disbursements[i].amount;
}
require(_totalDisbursed == msg.value, "Disbursement total != amount sent");
// Process disbursements.
for (uint256 i = 0; i < _numDisbursements; i++) {
uint256 _amount = _disbursements[i].amount;
address _addr = _disbursements[i].addr;
// Deliver the dispursement amount to the receiver. If the
// disbursement fails, the amount will be kept by the contract
// rather than reverting to prevent blocking progress on other
// disbursements.
// slither-disable-next-line calls-loop,reentrancy-events
(bool success, ) = _addr.call{ value: _amount, gas: 2300 }("");
if (success) emit DisbursementSuccess(_depositId, _addr, _amount);
else emit DisbursementFailed(_depositId, _addr, _amount);
unchecked {
_depositId += 1;
}
}
}
/**
* @notice Sends the contract's current balance to the owner.
*/
function withdrawBalance() external onlyOwner {
address _owner = owner();
uint256 balance = address(this).balance;
emit BalanceWithdrawn(_owner, balance);
payable(_owner).transfer(balance);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
contract FailingReceiver {
receive() external payable {
require(false, "FailingReceiver");
}
}
......@@ -12,17 +12,28 @@ import { Transactor } from "./Transactor.sol";
*/
contract AssetReceiver is Transactor {
/**
* Emitted when ETH is received by this address.
* @notice Emitted when ETH is received by this address.
*
* @param from Address that sent ETH to this contract.
*/
event ReceivedETH(address indexed from, uint256 amount);
/**
* Emitted when ETH is withdrawn from this address.
* @notice Emitted when ETH is withdrawn from this address.
*
* @param withdrawer Address that triggered the withdrawal.
* @param recipient Address that received the withdrawal.
* @param amount ETH amount withdrawn.
*/
event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);
/**
* Emitted when ERC20 tokens are withdrawn from this address.
* @notice Emitted when ERC20 tokens are withdrawn from this address.
*
* @param withdrawer Address that triggered the withdrawal.
* @param recipient Address that received the withdrawal.
* @param asset Address of the token being withdrawn.
* @param amount ERC20 amount withdrawn.
*/
event WithdrewERC20(
address indexed withdrawer,
......@@ -32,7 +43,12 @@ contract AssetReceiver is Transactor {
);
/**
* Emitted when ERC721 tokens are withdrawn from this address.
* @notice Emitted when ERC20 tokens are withdrawn from this address.
*
* @param withdrawer Address that triggered the withdrawal.
* @param recipient Address that received the withdrawal.
* @param asset Address of the token being withdrawn.
* @param id Token ID being withdrawn.
*/
event WithdrewERC721(
address indexed withdrawer,
......@@ -47,14 +63,14 @@ contract AssetReceiver is Transactor {
constructor(address _owner) Transactor(_owner) {}
/**
* Make sure we can receive ETH.
* @notice Make sure we can receive ETH.
*/
receive() external payable {
emit ReceivedETH(msg.sender, msg.value);
}
/**
* Withdraws full ETH balance to the recipient.
* @notice Withdraws full ETH balance to the recipient.
*
* @param _to Address to receive the ETH balance.
*/
......@@ -63,7 +79,7 @@ contract AssetReceiver is Transactor {
}
/**
* Withdraws partial ETH balance to the recipient.
* @notice Withdraws partial ETH balance to the recipient.
*
* @param _to Address to receive the ETH balance.
* @param _amount Amount of ETH to withdraw.
......@@ -75,7 +91,7 @@ contract AssetReceiver is Transactor {
}
/**
* Withdraws full ERC20 balance to the recipient.
* @notice Withdraws full ERC20 balance to the recipient.
*
* @param _asset ERC20 token to withdraw.
* @param _to Address to receive the ERC20 balance.
......@@ -85,7 +101,7 @@ contract AssetReceiver is Transactor {
}
/**
* Withdraws partial ERC20 balance to the recipient.
* @notice Withdraws partial ERC20 balance to the recipient.
*
* @param _asset ERC20 token to withdraw.
* @param _to Address to receive the ERC20 balance.
......@@ -103,7 +119,7 @@ contract AssetReceiver is Transactor {
}
/**
* Withdraws ERC721 token to the recipient.
* @notice Withdraws ERC721 token to the recipient.
*
* @param _asset ERC721 token to withdraw.
* @param _to Address to receive the ERC721 token.
......
......@@ -20,6 +20,7 @@ contract Transactor is Owned {
* @param _data Data to send with the call.
* @param _gas Amount of gas to send with the call.
* @param _value ETH value to send with the call.
*
* @return Boolean success value.
* @return Bytes data returned by the call.
*/
......@@ -38,6 +39,7 @@ contract Transactor is Owned {
* @param _target Address to call.
* @param _data Data to send with the call.
* @param _gas Amount of gas to send with the call.
*
* @return Boolean success value.
* @return Bytes data returned by the call.
*/
......
......@@ -7,17 +7,23 @@ import { IDripCheck } from "./IDripCheck.sol";
/**
* @title Drippie
* @notice Drippie is a system for managing automated contract interactions. A specific interaction
* is called a "drip" and can be executed according to some condition (called a dripcheck) and an
* execution interval. Drips cannot be executed faster than the execution interval. Drips can
* trigger arbitrary contract calls where the calling contract is this contract address. Drips can
* also send ETH value, which makes them ideal for keeping addresses sufficiently funded with ETH.
* Drippie is designed to be connected with smart contract automation services so that drips can be
* executed automatically. However, Drippie is specifically designed to be separated from these
* services so that trust assumptions are better compartmentalized.
* is called a "drip" and can be executed according to some condition (called a dripcheck)
* and an execution interval. Drips cannot be executed faster than the execution interval.
* Drips can trigger arbitrary contract calls where the calling contract is this contract
* address. Drips can also send ETH value, which makes them ideal for keeping addresses
* sufficiently funded with ETH. Drippie is designed to be connected with smart contract
* automation services so that drips can be executed automatically. However, Drippie is
* specifically designed to be separated from these services so that trust assumptions are
* better compartmentalized.
*/
contract Drippie is AssetReceiver {
/**
* Enum representing different status options for a given drip.
* @notice Enum representing different status options for a given drip.
*
* @custom:value NONE Drip does not exist.
* @custom:value ACTIVE Drip is active and can be executed.
* @custom:value PAUSED Drip is paused and cannot be executed until reactivated.
* @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.
*/
enum DripStatus {
NONE,
......@@ -27,7 +33,7 @@ contract Drippie is AssetReceiver {
}
/**
* Represents a drip action.
* @notice Represents a drip action.
*/
struct DripAction {
address payable target;
......@@ -36,7 +42,7 @@ contract Drippie is AssetReceiver {
}
/**
* Represents the configuration for a given drip.
* @notice Represents the configuration for a given drip.
*/
struct DripConfig {
uint256 interval;
......@@ -46,7 +52,7 @@ contract Drippie is AssetReceiver {
}
/**
* Represents the state of an active drip.
* @notice Represents the state of an active drip.
*/
struct DripState {
DripStatus status;
......@@ -56,7 +62,11 @@ contract Drippie is AssetReceiver {
}
/**
* Emitted when a new drip is created.
* @notice Emitted when a new drip is created.
*
* @param nameref Indexed name parameter (hashed).
* @param name Unindexed name parameter (unhashed).
* @param config Config for the created drip.
*/
event DripCreated(
// Emit name twice because indexed version is hashed.
......@@ -66,7 +76,11 @@ contract Drippie is AssetReceiver {
);
/**
* Emitted when a drip status is updated.
* @notice Emitted when a drip status is updated.
*
* @param nameref Indexed name parameter (hashed).
* @param name Unindexed name parameter (unhashed).
* @param status New drip status.
*/
event DripStatusUpdated(
// Emit name twice because indexed version is hashed.
......@@ -76,7 +90,12 @@ contract Drippie is AssetReceiver {
);
/**
* Emitted when a drip is executed.
* @notice Emitted when a drip is executed.
*
* @param nameref Indexed name parameter (hashed).
* @param name Unindexed name parameter (unhashed).
* @param executor Address that executed the drip.
* @param timestamp Time when the drip was executed.
*/
event DripExecuted(
// Emit name twice because indexed version is hashed.
......@@ -87,7 +106,7 @@ contract Drippie is AssetReceiver {
);
/**
* Maps from drip names to drip states.
* @notice Maps from drip names to drip states.
*/
mapping(string => DripState) public drips;
......@@ -97,9 +116,9 @@ contract Drippie is AssetReceiver {
constructor(address _owner) AssetReceiver(_owner) {}
/**
* Creates a new drip with the given name and configuration. Once created, drips cannot be
* modified in any way (this is a security measure). If you want to update a drip, simply pause
* (and potentially archive) the existing drip and create a new one.
* @notice Creates a new drip with the given name and configuration. Once created, drips cannot
* be modified in any way (this is a security measure). If you want to update a drip,
* simply pause (and potentially archive) the existing drip and create a new one.
*
* @param _name Name of the drip.
* @param _config Configuration for the drip.
......@@ -130,9 +149,10 @@ contract Drippie is AssetReceiver {
}
/**
* Sets the status for a given drip. The behavior of this function depends on the status that
* the user is trying to set. A drip can always move between ACTIVE and PAUSED, but it can
* never move back to NONE and once ARCHIVED, it can never move back to ACTIVE or PAUSED.
* @notice Sets the status for a given drip. The behavior of this function depends on the
* status that the user is trying to set. A drip can always move between ACTIVE and
* PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back
* to ACTIVE or PAUSED.
*
* @param _name Name of the drip to update.
* @param _status New drip status.
......@@ -184,9 +204,10 @@ contract Drippie is AssetReceiver {
}
/**
* Checks if a given drip is executable.
* @notice Checks if a given drip is executable.
*
* @param _name Drip to check.
*
* @return True if the drip is executable, false otherwise.
*/
function executable(string memory _name) public view returns (bool) {
......@@ -219,12 +240,12 @@ contract Drippie is AssetReceiver {
}
/**
* Triggers a drip. This function is deliberately left as a public function because the
* assumption being made here is that setting the drip to ACTIVE is an affirmative signal that
* the drip should be executable according to the drip parameters, drip check, and drip
* interval. Note that drip parameters are read entirely from the state and are not supplied as
* user input, so there should not be any way for a non-authorized user to influence the
* behavior of the drip.
* @notice Triggers a drip. This function is deliberately left as a public function because the
* assumption being made here is that setting the drip to ACTIVE is an affirmative
* signal that the drip should be executable according to the drip parameters, drip
* check, and drip interval. Note that drip parameters are read entirely from the state
* and are not supplied as user input, so there should not be any way for a
* non-authorized user to influence the behavior of the drip.
*
* @param _name Name of the drip to trigger.
*/
......
......@@ -10,6 +10,7 @@ import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-waffle'
import '@nomiclabs/hardhat-etherscan'
import '@eth-optimism/hardhat-deploy-config'
import '@typechain/hardhat'
import 'solidity-coverage'
import 'hardhat-gas-reporter'
import 'hardhat-deploy'
......@@ -92,6 +93,10 @@ const config: HardhatUserConfig = {
mocha: {
timeout: 50000,
},
typechain: {
outDir: 'dist/types',
target: 'ethers-v5',
},
solidity: {
compilers: [
{
......
{
"name": "@eth-optimism/contracts-periphery",
"version": "0.1.5",
"version": "0.2.0",
"description": "[Optimism] External (out-of-protocol) L1 and L2 smart contracts for Optimism",
"main": "dist/index",
"types": "dist/index",
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
"dist/types/*.ts",
"dist/types",
"artifacts/contracts/**/*.json",
"deployments/**/*.json",
"L1",
"L2",
"libraries",
"standards"
"contracts"
],
"scripts": {
"build": "yarn build:hh",
......@@ -57,10 +54,10 @@
},
"devDependencies": {
"@defi-wonderland/smock": "^2.0.7",
"@eth-optimism/contracts": "^0.5.29",
"@eth-optimism/contracts-bedrock": "^0.4.1",
"@eth-optimism/core-utils": "^0.9.0",
"@eth-optimism/hardhat-deploy-config": "^0.2.0",
"@eth-optimism/contracts": "^0.5.30",
"@eth-optimism/contracts-bedrock": "^0.5.0",
"@eth-optimism/core-utils": "^0.9.1",
"@eth-optimism/hardhat-deploy-config": "^0.2.1",
"@ethersproject/hardware-wallets": "^5.6.1",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-etherscan": "^3.0.3",
......@@ -71,6 +68,8 @@
"@types/chai": "^4.2.18",
"@types/mocha": "^8.2.2",
"@types/node": "^17.0.21",
"@typechain/ethers-v5": "^10.1.0",
"@typechain/hardhat": "^6.1.2",
"babel-eslint": "^10.1.0",
"chai": "^4.3.4",
"copyfiles": "^2.3.0",
......@@ -92,6 +91,7 @@
"solhint": "^3.3.6",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.7.17",
"ts-node": "^10.8.2"
"ts-node": "^10.8.2",
"typechain": "^8.1.0"
}
}
......@@ -10,11 +10,8 @@ import {
} from '@defi-wonderland/smock'
import ICrossDomainMessenger from '@eth-optimism/contracts/artifacts/contracts/libraries/bridge/ICrossDomainMessenger.sol/ICrossDomainMessenger.json'
import { expect } from '../../../setup'
import {
NON_NULL_BYTES32,
NON_ZERO_ADDRESS,
} from '../../../../../contracts/test/helpers'
import { NON_NULL_BYTES32, NON_ZERO_ADDRESS } from '../../helpers'
import { expect } from '../../setup'
const ERR_INVALID_MESSENGER = 'OVM_XCHAIN: messenger contract unauthenticated'
const ERR_INVALID_X_DOMAIN_MSG_SENDER =
......
import { ethers } from 'hardhat'
import { Contract, BigNumber } from 'ethers'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
import { expect } from '../../setup'
import { deploy } from '../../helpers'
const initialMinDepositAmount = ethers.utils.parseEther('0.01')
const initialMaxDepositAmount = ethers.utils.parseEther('1')
const initialMaxBalance = ethers.utils.parseEther('2')
describe('TeleportrDeposit', async () => {
let signer1: SignerWithAddress
let signer2: SignerWithAddress
before(async () => {
;[signer1, signer2] = await ethers.getSigners()
})
let TeleportrDeposit: Contract
before(async () => {
TeleportrDeposit = await deploy('TeleportrDeposit', {
args: [
initialMinDepositAmount,
initialMaxDepositAmount,
initialMaxBalance,
],
})
})
describe('receive', async () => {
const oneETH = ethers.utils.parseEther('1.0')
const twoETH = ethers.utils.parseEther('2.0')
it('should revert if deposit amount is less than min amount', async () => {
await expect(
signer1.sendTransaction({
to: TeleportrDeposit.address,
value: ethers.utils.parseEther('0.001'),
})
).to.be.revertedWith('Deposit amount is too small')
})
it('should revert if deposit amount is greater than max amount', async () => {
await expect(
signer1.sendTransaction({
to: TeleportrDeposit.address,
value: ethers.utils.parseEther('1.1'),
})
).to.be.revertedWith('Deposit amount is too big')
})
it('should emit EtherReceived if called by non-owner', async () => {
await expect(
signer2.sendTransaction({
to: TeleportrDeposit.address,
value: oneETH,
})
)
.to.emit(TeleportrDeposit, 'EtherReceived')
.withArgs(BigNumber.from('0'), signer2.address, oneETH)
})
it('should increase the contract balance by deposit amount', async () => {
expect(
await ethers.provider.getBalance(TeleportrDeposit.address)
).to.equal(oneETH)
})
it('should emit EtherReceived if called by owner', async () => {
await expect(
signer1.sendTransaction({
to: TeleportrDeposit.address,
value: oneETH,
})
)
.to.emit(TeleportrDeposit, 'EtherReceived')
.withArgs(BigNumber.from('1'), signer1.address, oneETH)
})
it('should increase the contract balance by deposit amount', async () => {
expect(
await ethers.provider.getBalance(TeleportrDeposit.address)
).to.equal(twoETH)
})
it('should revert if deposit will exceed max balance', async () => {
await expect(
signer1.sendTransaction({
to: TeleportrDeposit.address,
value: initialMinDepositAmount,
})
).to.be.revertedWith('Contract max balance exceeded')
})
})
describe('withdrawBalance', async () => {
let initialContractBalance: BigNumber
let initialSignerBalance: BigNumber
before(async () => {
initialContractBalance = await ethers.provider.getBalance(
TeleportrDeposit.address
)
initialSignerBalance = await signer1.getBalance()
})
it('should revert if called by non-owner', async () => {
await expect(
TeleportrDeposit.connect(signer2).withdrawBalance()
).to.be.revertedWith('Ownable: caller is not the owner')
})
it('should emit BalanceWithdrawn if called by owner', async () => {
await expect(TeleportrDeposit.withdrawBalance())
.to.emit(TeleportrDeposit, 'BalanceWithdrawn')
.withArgs(signer1.address, initialContractBalance)
})
it('should leave the contract with zero balance', async () => {
expect(
await ethers.provider.getBalance(TeleportrDeposit.address)
).to.equal(ethers.utils.parseEther('0'))
})
it('should credit owner with contract balance - fees', async () => {
const expSignerBalance = initialSignerBalance.add(initialContractBalance)
expect(await signer1.getBalance()).to.be.closeTo(
expSignerBalance,
10 ** 15
)
})
})
describe('setMinAmount', async () => {
const newMinDepositAmount = ethers.utils.parseEther('0.02')
it('should revert if called by non-owner', async () => {
await expect(
TeleportrDeposit.connect(signer2).setMinAmount(newMinDepositAmount)
).to.be.revertedWith('Ownable: caller is not the owner')
})
it('should emit MinDepositAmountSet if called by owner', async () => {
await expect(TeleportrDeposit.setMinAmount(newMinDepositAmount))
.to.emit(TeleportrDeposit, 'MinDepositAmountSet')
.withArgs(initialMinDepositAmount, newMinDepositAmount)
})
it('should have updated minDepositAmount after success', async () => {
expect(await TeleportrDeposit.minDepositAmount()).to.be.eq(
newMinDepositAmount
)
})
})
describe('setMaxAmount', async () => {
const newMaxDepositAmount = ethers.utils.parseEther('2')
it('should revert if called non-owner', async () => {
await expect(
TeleportrDeposit.connect(signer2).setMaxAmount(newMaxDepositAmount)
).to.be.revertedWith('Ownable: caller is not the owner')
})
it('should emit MaxDepositAmountSet if called by owner', async () => {
await expect(TeleportrDeposit.setMaxAmount(newMaxDepositAmount))
.to.emit(TeleportrDeposit, 'MaxDepositAmountSet')
.withArgs(initialMaxDepositAmount, newMaxDepositAmount)
})
it('should have an updated maxDepositAmount after success', async () => {
expect(await TeleportrDeposit.maxDepositAmount()).to.be.eq(
newMaxDepositAmount
)
})
})
describe('setMaxBalance', async () => {
const newMaxBalance = ethers.utils.parseEther('2000')
it('should revert if called by non-owner', async () => {
await expect(
TeleportrDeposit.connect(signer2).setMaxBalance(newMaxBalance)
).to.be.revertedWith('Ownable: caller is not the owner')
})
it('should emit MaxBalanceSet if called by owner', async () => {
await expect(TeleportrDeposit.setMaxBalance(newMaxBalance))
.to.emit(TeleportrDeposit, 'MaxBalanceSet')
.withArgs(initialMaxBalance, newMaxBalance)
})
it('should have an updated maxBalance after success', async () => {
expect(await TeleportrDeposit.maxBalance()).to.be.eq(newMaxBalance)
})
})
})
......@@ -5,11 +5,8 @@ import { smock, FakeContract } from '@defi-wonderland/smock'
import ICrossDomainMessenger from '@eth-optimism/contracts/artifacts/contracts/libraries/bridge/ICrossDomainMessenger.sol/ICrossDomainMessenger.json'
import { toRpcHexString } from '@eth-optimism/core-utils'
import { expect } from '../../../setup'
import {
NON_NULL_BYTES32,
NON_ZERO_ADDRESS,
} from '../../../../../contracts/test/helpers'
import { NON_NULL_BYTES32, NON_ZERO_ADDRESS } from '../../helpers'
import { expect } from '../../setup'
const ERR_ALREADY_INITIALIZED = 'Initializable: contract is already initialized'
const ERR_INVALID_MESSENGER = 'OVM_XCHAIN: messenger contract unauthenticated'
......
import { ethers } from 'hardhat'
import { Contract, BigNumber } from 'ethers'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
import { expect } from '../../setup'
import { deploy } from '../../helpers'
const zeroETH = ethers.utils.parseEther('0.0')
const oneETH = ethers.utils.parseEther('1.0')
const twoETH = ethers.utils.parseEther('2.0')
describe('TeleportrDisburser', async () => {
let signer1: SignerWithAddress
let signer2: SignerWithAddress
before(async () => {
;[signer1, signer2] = await ethers.getSigners()
})
let TeleportrDisburser: Contract
let FailingReceiver: Contract
before(async () => {
TeleportrDisburser = await deploy('TeleportrDisburser')
FailingReceiver = await deploy('FailingReceiver')
})
describe('disburse checks', async () => {
it('should revert if called by non-owner', async () => {
await expect(
TeleportrDisburser.connect(signer2).disburse(0, [], { value: oneETH })
).to.be.revertedWith('Ownable: caller is not the owner')
})
it('should revert if no disbursements is zero length', async () => {
await expect(
TeleportrDisburser.disburse(0, [], { value: oneETH })
).to.be.revertedWith('No disbursements')
})
it('should revert if nextDepositId does not match expected value', async () => {
await expect(
TeleportrDisburser.disburse(1, [[oneETH, signer2.address]], {
value: oneETH,
})
).to.be.revertedWith('Unexpected next deposit id')
})
it('should revert if msg.value does not match total to disburse', async () => {
await expect(
TeleportrDisburser.disburse(0, [[oneETH, signer2.address]], {
value: zeroETH,
})
).to.be.revertedWith('Disbursement total != amount sent')
})
})
describe('disburse single success', async () => {
let signer1InitialBalance: BigNumber
let signer2InitialBalance: BigNumber
before(async () => {
signer1InitialBalance = await ethers.provider.getBalance(signer1.address)
signer2InitialBalance = await ethers.provider.getBalance(signer2.address)
})
it('should emit DisbursementSuccess for successful disbursement', async () => {
await expect(
TeleportrDisburser.disburse(0, [[oneETH, signer2.address]], {
value: oneETH,
})
)
.to.emit(TeleportrDisburser, 'DisbursementSuccess')
.withArgs(BigNumber.from(0), signer2.address, oneETH)
})
it('should show one total disbursement', async () => {
expect(await TeleportrDisburser.totalDisbursements()).to.be.equal(
BigNumber.from(1)
)
})
it('should leave contract balance at zero ETH', async () => {
expect(
await ethers.provider.getBalance(TeleportrDisburser.address)
).to.be.equal(zeroETH)
})
it('should increase recipients balance by disbursement amount', async () => {
expect(await ethers.provider.getBalance(signer2.address)).to.be.equal(
signer2InitialBalance.add(oneETH)
)
})
it('should decrease owners balance by disbursement amount - fees', async () => {
expect(await ethers.provider.getBalance(signer1.address)).to.be.closeTo(
signer1InitialBalance.sub(oneETH),
10 ** 15
)
})
})
describe('disburse single failure', async () => {
let signer1InitialBalance: BigNumber
before(async () => {
signer1InitialBalance = await ethers.provider.getBalance(signer1.address)
})
it('should emit DisbursementFailed for failed disbursement', async () => {
await expect(
TeleportrDisburser.disburse(1, [[oneETH, FailingReceiver.address]], {
value: oneETH,
})
)
.to.emit(TeleportrDisburser, 'DisbursementFailed')
.withArgs(BigNumber.from(1), FailingReceiver.address, oneETH)
})
it('should show two total disbursements', async () => {
expect(await TeleportrDisburser.totalDisbursements()).to.be.equal(
BigNumber.from(2)
)
})
it('should leave contract with disbursement amount', async () => {
expect(
await ethers.provider.getBalance(TeleportrDisburser.address)
).to.be.equal(oneETH)
})
it('should leave recipients balance at zero ETH', async () => {
expect(
await ethers.provider.getBalance(FailingReceiver.address)
).to.be.equal(zeroETH)
})
it('should decrease owners balance by disbursement amount - fees', async () => {
expect(await ethers.provider.getBalance(signer1.address)).to.be.closeTo(
signer1InitialBalance.sub(oneETH),
10 ** 15
)
})
})
describe('withdrawBalance', async () => {
let signer1InitialBalance: BigNumber
let disburserInitialBalance: BigNumber
before(async () => {
signer1InitialBalance = await ethers.provider.getBalance(signer1.address)
disburserInitialBalance = await ethers.provider.getBalance(
TeleportrDisburser.address
)
})
it('should revert if called by non-owner', async () => {
await expect(
TeleportrDisburser.connect(signer2).withdrawBalance()
).to.be.revertedWith('Ownable: caller is not the owner')
})
it('should emit BalanceWithdrawn if called by owner', async () => {
await expect(TeleportrDisburser.withdrawBalance())
.to.emit(TeleportrDisburser, 'BalanceWithdrawn')
.withArgs(signer1.address, oneETH)
})
it('should leave contract with zero balance', async () => {
expect(
await ethers.provider.getBalance(TeleportrDisburser.address)
).to.equal(zeroETH)
})
it('should credit owner with contract balance - fees', async () => {
expect(await ethers.provider.getBalance(signer1.address)).to.be.closeTo(
signer1InitialBalance.add(disburserInitialBalance),
10 ** 15
)
})
})
describe('disburse multiple', async () => {
let signer1InitialBalance: BigNumber
let signer2InitialBalance: BigNumber
before(async () => {
signer1InitialBalance = await ethers.provider.getBalance(signer1.address)
signer2InitialBalance = await ethers.provider.getBalance(signer2.address)
})
it('should emit DisbursementSuccess for successful disbursement', async () => {
await expect(
TeleportrDisburser.disburse(
2,
[
[oneETH, signer2.address],
[oneETH, FailingReceiver.address],
],
{ value: twoETH }
)
).to.not.be.reverted
})
it('should show four total disbursements', async () => {
expect(await TeleportrDisburser.totalDisbursements()).to.be.equal(
BigNumber.from(4)
)
})
it('should leave contract balance with failed disbursement amount', async () => {
expect(
await ethers.provider.getBalance(TeleportrDisburser.address)
).to.be.equal(oneETH)
})
it('should increase success recipients balance by disbursement amount', async () => {
expect(await ethers.provider.getBalance(signer2.address)).to.be.equal(
signer2InitialBalance.add(oneETH)
)
})
it('should leave failed recipients balance at zero ETH', async () => {
expect(
await ethers.provider.getBalance(FailingReceiver.address)
).to.be.equal(zeroETH)
})
it('should decrease owners balance by disbursement 2*amount - fees', async () => {
expect(await ethers.provider.getBalance(signer1.address)).to.be.closeTo(
signer1InitialBalance.sub(twoETH),
10 ** 15
)
})
})
})
export const NON_NULL_BYTES32 = '0x' + '11'.repeat(32)
export const NON_ZERO_ADDRESS = '0x' + '11'.repeat(20)
export * from './deploy'
export * from './solidity'
export * from './constants'
# Changelog
## 0.5.30
### Patch Changes
- 6e3449ba: Properly export typechain
- Updated dependencies [f9fee446]
- @eth-optimism/core-utils@0.9.1
## 0.5.29
### Patch Changes
......
{
"name": "@eth-optimism/contracts",
"version": "0.5.29",
"version": "0.5.30",
"description": "[Optimism] L1 and L2 smart contracts for Optimism",
"main": "dist/index",
"types": "dist/index",
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
"dist/types/*.ts",
"dist/types",
"artifacts/contracts/**/*.json",
"deployments/**/*.json",
"chugsplash",
......@@ -57,14 +57,14 @@
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"dependencies": {
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/core-utils": "0.9.1",
"@ethersproject/abstract-provider": "^5.6.1",
"@ethersproject/abstract-signer": "^5.6.2"
},
"devDependencies": {
"@codechecks/client": "^0.1.11",
"@defi-wonderland/smock": "^2.0.2",
"@eth-optimism/hardhat-deploy-config": "^0.2.0",
"@eth-optimism/hardhat-deploy-config": "^0.2.1",
"@ethersproject/abi": "^5.6.3",
"@ethersproject/bytes": "^5.6.1",
"@ethersproject/hardware-wallets": "^5.6.1",
......@@ -76,8 +76,8 @@
"@openzeppelin/contracts": "4.3.2",
"@openzeppelin/contracts-upgradeable": "4.3.2",
"@primitivefi/hardhat-dodoc": "^0.1.3",
"@typechain/ethers-v5": "^8.0.2",
"@typechain/hardhat": "^3.0.0",
"@typechain/ethers-v5": "^10.1.0",
"@typechain/hardhat": "^6.1.2",
"@types/chai": "^4.2.18",
"@types/lodash": "^4.14.168",
"@types/mkdirp": "^1.0.1",
......@@ -111,7 +111,7 @@
"squirrelly": "^8.0.8",
"ts-generator": "0.0.8",
"ts-node": "^10.0.0",
"typechain": "^6.0.2",
"typechain": "^8.1.0",
"typescript": "^4.6.2"
},
"peerDependencies": {
......
# @eth-optimism/core-utils
## 0.9.1
### Patch Changes
- f9fee446: Move the `DepositTx` type to `core-utils`. This way it can be more easily used across projects
## 0.9.0
### Minor Changes
......
{
"name": "@eth-optimism/core-utils",
"version": "0.9.0",
"version": "0.9.1",
"description": "[Optimism] Core typescript utilities",
"main": "dist/index",
"types": "dist/index",
......
# data transport layer
## 0.5.39
### Patch Changes
- 6e3449ba: Upgrade import path for new typechain
- Updated dependencies [6e3449ba]
- Updated dependencies [f9fee446]
- @eth-optimism/contracts@0.5.30
- @eth-optimism/core-utils@0.9.1
- @eth-optimism/common-ts@0.6.1
## 0.5.38
### Patch Changes
......
{
"private": true,
"name": "@eth-optimism/data-transport-layer",
"version": "0.5.38",
"version": "0.5.39",
"description": "[Optimism] Service for shuttling data from L1 into L2",
"main": "dist/index",
"types": "dist/index",
......@@ -36,9 +36,9 @@
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"dependencies": {
"@eth-optimism/common-ts": "0.6.0",
"@eth-optimism/contracts": "0.5.29",
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/common-ts": "0.6.1",
"@eth-optimism/contracts": "0.5.30",
"@eth-optimism/core-utils": "0.9.1",
"@ethersproject/providers": "^5.6.8",
"@ethersproject/transactions": "^5.6.2",
"@sentry/node": "^6.3.1",
......
......@@ -8,7 +8,7 @@ import {
BatchType,
SequencerBatch,
} from '@eth-optimism/core-utils'
import { SequencerBatchAppendedEvent } from '@eth-optimism/contracts/dist/types/CanonicalTransactionChain'
import { SequencerBatchAppendedEvent } from '@eth-optimism/contracts/dist/types/contracts/L1/rollup/CanonicalTransactionChain'
/* Imports: Internal */
import { MissingElementError } from './errors'
......
/* Imports: External */
import { StateBatchAppendedEvent } from '@eth-optimism/contracts/dist/types/StateCommitmentChain'
import { StateBatchAppendedEvent } from '@eth-optimism/contracts/dist/types/contracts/L1/rollup/StateCommitmentChain'
import { getContractFactory } from '@eth-optimism/contracts'
import { BigNumber } from 'ethers'
......
/* Imports: External */
import { BigNumber } from 'ethers'
import { TransactionEnqueuedEvent } from '@eth-optimism/contracts/dist/types/CanonicalTransactionChain'
import { TransactionEnqueuedEvent } from '@eth-optimism/contracts/dist/types/contracts/L1/rollup/CanonicalTransactionChain'
/* Imports: Internal */
import { MissingElementError } from './errors'
......
# @eth-optimism/drippie-mon
## 0.3.7
### Patch Changes
- Updated dependencies [032f7214]
- @eth-optimism/sdk@1.3.0
## 0.3.6
### Patch Changes
- Updated dependencies [95fc3fbf]
- Updated dependencies [019657db]
- Updated dependencies [6ff5c0a3]
- Updated dependencies [119f0e97]
- Updated dependencies [9c8b1f00]
- Updated dependencies [8a335b7b]
- Updated dependencies [f9fee446]
- Updated dependencies [89d01f2e]
- @eth-optimism/contracts-periphery@0.2.0
- @eth-optimism/core-utils@0.9.1
- @eth-optimism/sdk@1.2.1
- @eth-optimism/common-ts@0.6.1
## 0.3.5
### Patch Changes
......
{
"private": true,
"name": "@eth-optimism/drippie-mon",
"version": "0.3.5",
"version": "0.3.7",
"description": "[Optimism] Service for monitoring Drippie instances",
"main": "dist/index",
"types": "dist/index",
......@@ -32,10 +32,10 @@
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"dependencies": {
"@eth-optimism/common-ts": "0.6.0",
"@eth-optimism/contracts-periphery": "0.1.5",
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/sdk": "1.2.0",
"@eth-optimism/common-ts": "0.6.1",
"@eth-optimism/contracts-periphery": "0.2.0",
"@eth-optimism/core-utils": "0.9.1",
"@eth-optimism/sdk": "1.3.0",
"ethers": "^5.6.8"
},
"devDependencies": {
......
# @eth-optimism/fault-detector
## 0.2.4
### Patch Changes
- 89d01f2e: Update dev deps
- Updated dependencies [6e3449ba]
- Updated dependencies [f9fee446]
- @eth-optimism/contracts@0.5.30
- @eth-optimism/core-utils@0.9.1
- @eth-optimism/sdk@1.2.1
- @eth-optimism/common-ts@0.6.1
## 0.2.3
### Patch Changes
......
{
"private": true,
"name": "@eth-optimism/fault-detector",
"version": "0.2.3",
"version": "0.2.4",
"description": "[Optimism] Service for detecting faulty L2 output proposals",
"main": "dist/index",
"types": "dist/index",
......@@ -47,10 +47,10 @@
"ts-node": "^10.8.2"
},
"dependencies": {
"@eth-optimism/common-ts": "^0.6.0",
"@eth-optimism/contracts": "^0.5.29",
"@eth-optimism/core-utils": "^0.9.0",
"@eth-optimism/sdk": "^1.2.0",
"@eth-optimism/common-ts": "^0.6.1",
"@eth-optimism/contracts": "^0.5.30",
"@eth-optimism/core-utils": "^0.9.1",
"@eth-optimism/sdk": "^1.2.1",
"@ethersproject/abstract-provider": "^5.6.1"
}
}
# @eth-optimism/hardhat-deploy-config
## 0.2.1
### Patch Changes
- 2fd0a2fe: Use lazyObject
- 89d01f2e: Update dev deps
## 0.2.0
### Minor Changes
- 27234f68: Initial release of hardhat-deploy-config
......
{
"name": "@eth-optimism/hardhat-deploy-config",
"version": "0.2.0",
"version": "0.2.1",
"description": "[Optimism] Hardhat deploy configuration plugin",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
......
......@@ -27,9 +27,9 @@
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"devDependencies": {
"@eth-optimism/contracts": "0.5.29",
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/sdk": "1.2.0",
"@eth-optimism/contracts": "0.5.30",
"@eth-optimism/core-utils": "0.9.1",
"@eth-optimism/sdk": "1.3.0",
"@ethersproject/abstract-provider": "^5.6.1",
"chai-as-promised": "^7.1.1",
"chai": "^4.3.4",
......
# @eth-optimism/message-relayer
## 0.5.6
### Patch Changes
- Updated dependencies [032f7214]
- @eth-optimism/sdk@1.3.0
## 0.5.5
### Patch Changes
- Updated dependencies [f9fee446]
- @eth-optimism/core-utils@0.9.1
- @eth-optimism/sdk@1.2.1
- @eth-optimism/common-ts@0.6.1
## 0.5.4
### Patch Changes
......
{
"private": true,
"name": "@eth-optimism/message-relayer",
"version": "0.5.4",
"version": "0.5.6",
"description": "[Optimism] Service for automatically relaying L2 to L1 transactions",
"main": "dist/index",
"types": "dist/index",
......@@ -31,9 +31,9 @@
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"dependencies": {
"@eth-optimism/common-ts": "0.6.0",
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/sdk": "1.2.0",
"@eth-optimism/common-ts": "0.6.1",
"@eth-optimism/core-utils": "0.9.1",
"@eth-optimism/sdk": "1.3.0",
"ethers": "^5.6.8"
},
"devDependencies": {
......
# @eth-optimism/replica-healthcheck
## 1.1.5
### Patch Changes
- Updated dependencies [f9fee446]
- @eth-optimism/core-utils@0.9.1
- @eth-optimism/common-ts@0.6.1
## 1.1.4
### Patch Changes
......
{
"private": true,
"name": "@eth-optimism/replica-healthcheck",
"version": "1.1.4",
"version": "1.1.5",
"description": "[Optimism] Service for monitoring the health of replica nodes",
"main": "dist/index",
"types": "dist/index",
......@@ -32,8 +32,8 @@
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"dependencies": {
"@eth-optimism/common-ts": "0.6.0",
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/common-ts": "0.6.1",
"@eth-optimism/core-utils": "0.9.1",
"@ethersproject/abstract-provider": "^5.6.1"
},
"devDependencies": {
......
# @eth-optimism/sdk
## 1.3.0
### Minor Changes
- 032f7214: Update Goerli SDK addresses for new Goerli testnet
## 1.2.1
### Patch Changes
- Updated dependencies [6e3449ba]
- Updated dependencies [f9fee446]
- @eth-optimism/contracts@0.5.30
- @eth-optimism/core-utils@0.9.1
## 1.2.0
### Minor Changes
......
{
"name": "@eth-optimism/sdk",
"version": "1.2.0",
"version": "1.3.0",
"description": "[Optimism] Tools for working with Optimism",
"main": "dist/index",
"types": "dist/index",
......@@ -46,8 +46,8 @@
"mocha": "^10.0.0"
},
"dependencies": {
"@eth-optimism/contracts": "0.5.29",
"@eth-optimism/core-utils": "0.9.0",
"@eth-optimism/contracts": "0.5.30",
"@eth-optimism/core-utils": "0.9.1",
"lodash": "^4.17.21",
"merkletreejs": "^0.2.27",
"rlp": "^2.2.7"
......
......@@ -84,15 +84,15 @@ export const CONTRACT_ADDRESSES: {
},
[L2ChainID.OPTIMISM_GOERLI]: {
l1: {
AddressManager: '0x2F7E3cAC91b5148d336BbffB224B4dC79F09f01D' as const,
AddressManager: '0xfA5b622409E1782597952a4A78c1D34CF32fF5e2' as const,
L1CrossDomainMessenger:
'0xEcC89b9EDD804850C4F343A278Be902be11AaF42' as const,
L1StandardBridge: '0x73298186A143a54c20ae98EEE5a025bD5979De02' as const,
'0x5086d1eEF304eb5284A0f6720f79403b4e9bE294' as const,
L1StandardBridge: '0x636Af16bf2f682dD3109e60102b8E1A089FedAa8' as const,
StateCommitmentChain:
'0x1afcA918eff169eE20fF8AB6Be75f3E872eE1C1A' as const,
'0x72281826E90dD8A65Ab686fF254eb45Be426DD22' as const,
CanonicalTransactionChain:
'0x2ebA8c4EfDB39A8Cd8f9eD65c50ec079f7CEBD81' as const,
BondManager: '0xE5AE60bD6F8DEe4D0c2BC9268e23B92F1cacC58F' as const,
'0x607F755149cFEB3a14E1Dc3A4E2450Cde7dfb04D' as const,
BondManager: '0xfC2ab6987C578218f99E85d61Dcf4814A26637Bd' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
......
# Versioning
## Go modules
Go modules that are currently versioned:
```text
./op-batcher
./op-bindings
./op-node
./op-proposer
./op-e2e
```
Go modules which are not yet versioned:
```text
./batch-submitter (changesets)
./bss-core
./gas-oracle (changesets)
./indexer (changesets)
./l2geth (changesets)
./l2geth-exporter (changesets)
./op-exporter (changesets)
./proxyd (changesets)
./teleportr (changesets)
./state-surgery
```
### versioning process
Since changesets versioning is not compatible with Go we are moving away from it.
Starting with new bedrock modules, Go-compatible tags will be used,
formatted as `modulename/vX.Y.Z` where `vX.Y.Z` is semver.
## Typescript
See Changesets.
......@@ -3175,20 +3175,21 @@
dependencies:
ethers "^5.0.2"
"@typechain/ethers-v5@^8.0.2":
version "8.0.5"
resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-8.0.5.tgz#d469420e9a73deb7fa076cde9edb45d713dd1b8c"
integrity sha512-ntpj4cS3v4WlDu+hSKSyj9A3o1tKtWC30RX1gobeYymZColeJiUemC1Kgfa0MWGmInm5CKxoHVhEvYVgPOZn1A==
"@typechain/hardhat@^6.1.2":
version "6.1.2"
resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-6.1.2.tgz#d3beccc6937d93f9b437616b741f839a8b953693"
integrity sha512-k4Ea3pVITKB2DH8p1a5U38cyy7KZPD04Spo4q5b4wO+n2mT+uAz5dxckPtbczn/Kk5wiFq+ZkuOtw5ZKFhL/+w==
dependencies:
fs-extra "^9.1.0"
lodash "^4.17.15"
ts-essentials "^7.0.1"
"@typechain/hardhat@^3.0.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-3.1.0.tgz#88bd9e9d55e30fbece6fbb34c03ecd40a8b2013a"
integrity sha512-C6Be6l+vTpao19PvMH2CB/lhL1TRLkhdPkvQCF/zqkY1e+0iqY2Bb9Jd3PTt6I8QvMm89ZDerrCJC9927ZHmlg==
"@typechain/hardhat@^6.1.2":
version "6.1.2"
resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-6.1.2.tgz#d3beccc6937d93f9b437616b741f839a8b953693"
integrity sha512-k4Ea3pVITKB2DH8p1a5U38cyy7KZPD04Spo4q5b4wO+n2mT+uAz5dxckPtbczn/Kk5wiFq+ZkuOtw5ZKFhL/+w==
dependencies:
fs-extra "^9.1.0"
lodash "^4.17.15"
"@types/abstract-leveldown@*":
version "5.0.2"
......@@ -17127,22 +17128,6 @@ typechain@^3.0.0:
ts-essentials "^6.0.3"
ts-generator "^0.1.1"
typechain@^6.0.2:
version "6.1.0"
resolved "https://registry.yarnpkg.com/typechain/-/typechain-6.1.0.tgz#462a35f555accf870689d1ba5698749108d0ce81"
integrity sha512-GGfkK0p3fUgz8kYxjSS4nKcWXE0Lo+teHTetghousIK5njbNoYNDlwn91QIyD181L3fVqlTvBE0a/q3AZmjNfw==
dependencies:
"@types/prettier" "^2.1.1"
debug "^4.1.1"
fs-extra "^7.0.0"
glob "^7.1.6"
js-sha3 "^0.8.0"
lodash "^4.17.15"
mkdirp "^1.0.4"
prettier "^2.1.2"
ts-command-line-args "^2.2.0"
ts-essentials "^7.0.1"
typechain@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.1.0.tgz#fc4902ce596519cb2ccfd012e4ddf92a9945b569"
......
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